当前位置: 代码迷 >> Android >> Android 反照调用资源和id
  详细解决方案

Android 反照调用资源和id

热度:42   发布时间:2016-04-28 02:57:34.0
Android 反射调用资源和id

本文介绍利用反射调用资源和id

提出问题:

       app有一种叫应用墙的广告,应用墙是在你的程序中弹出一个Activity来展示广告,比如豌豆广点通等,集成的时候需要将资源通过复制添加到自己的项目中,但是app墙的代码是封装好的jar代码。不是源码,看不到,也不能修改。那么jar中的代码是如何加载本地资源的呢?


       自己的项目中加载资源的时候都是通过本项目的R文件来初始化资源,R文件是你自己的项目的R文件,和项目有关,如果第三方的jar文件中使用的R是来第三方SDK项目中的资源R,代码更换了项目之后铁定了是找不到你复制过来的资源的。那么这时候就需要通过特殊的方式来加载资源了,以便于调用在被集成的app中的资源。


通过原始的java反射机制的方式调用资源:

这只是一种方式,还有其他的方式。

IDHelper.java

public class IDHelper {	public static int getLayout(Context mContext, String layoutName) {		return ResourceHelper.getInstance(mContext).getLayoutId(layoutName);	}	public static int getViewID(Context mContext, String IDName) {		return ResourceHelper.getInstance(mContext).getId(IDName);	}	public static int getDrawable(Context context, String drawableName) {		return ResourceHelper.getInstance(context).getDrawableId(drawableName);	}	public static int getAttr(Context context, String attrName) {		return ResourceHelper.getInstance(context).getAttrId(attrName);	}	public static int getString(Context context, String stringName) {		return ResourceHelper.getInstance(context).getStringId(stringName);	}}


ResourceHelper.java

public class ResourceHelper {	private static ResourceHelper mResource = null;	private static String mPackagename = null;	private static Class<?> mLayout = null;	private static Class<?> mDrawable = null;	private static Class<?> mID = null;	private static Class<?> mString = null;	private static Class<?> mAttr = null;	public static ResourceHelper getInstance(Context context) {		if (mResource == null) {			mPackagename = (mPackagename == null ? context.getPackageName()					: mPackagename);			mResource = new ResourceHelper(mPackagename);		}		return mResource;	}	public ResourceHelper(String packageName) {		try {			mLayout = Class.forName(packageName + ".R$layout");		} catch (ClassNotFoundException e) {			e.printStackTrace();		}		try {			mDrawable = Class.forName(packageName + ".R$drawable");		} catch (ClassNotFoundException e) {			e.printStackTrace();		}		try {			mID = Class.forName(packageName + ".R$id");		} catch (ClassNotFoundException e) {			e.printStackTrace();		}		try {			mString = Class.forName(packageName + ".R$string");		} catch (ClassNotFoundException e) {			e.printStackTrace();		}		try {			mAttr = Class.forName(packageName + ".R$attr");		} catch (ClassNotFoundException e) {			e.printStackTrace();		}	}	private int getResourceId(Class<?> classType, String resourceName) {		if (classType == null) {			throw new IllegalArgumentException(					"ResClass is not initialized. Please make sure you have added neccessary resources. Also make sure you have "							+ mPackagename							+ ".R$* configured in obfuscation. field="							+ resourceName);		}		try {			Field field = classType.getField(resourceName);			return field.getInt(resourceName);		} catch (Exception e) {			e.printStackTrace();			Log.e("ResourceHelper",					"Error getting resource. Make sure you have copied all resources (res/) from SDK to your project.");		}		return -1;	}	//	public int getDrawableId(String resourceName) {		return getResourceId(mDrawable, resourceName);	}	public int getLayoutId(String resourceName) {		return getResourceId(mLayout, resourceName);	}	public int getId(String resourceName) {		return getResourceId(mID, resourceName);	}	public int getStringId(String resourceName) {		return getResourceId(mString, resourceName);	}	public int getAttrId(String resourceName) {		return getResourceId(mAttr, resourceName);	}}

使用:

使用的时候不需要通过R来调用资源

public class MainActivity extends ActionBarActivity {	private Button mButton;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(IDHelper.getLayout(getApplicationContext(),				"activity_main"));//字符串是layout文件的名字		initView();	}	private void initView() {		mButton = (Button) findViewById(IDHelper.getViewID(				getApplicationContext(), "button1"));		mButton.setOnClickListener(new OnClickListener() {			@Override			public void onClick(View arg0) {				Toast.makeText(getApplicationContext(), "HelloWorld",						Toast.LENGTH_LONG).show();//字符串是控件的id			}		});	}}



通过Android API 的通过反射获取id的方法

Context.getResources().getIdentifier("activity_main", "layout",                 paramContext.getPackageName()); 



  相关解决方案