標籤:反射調用資源 android反射調用資源 android反射初始化資源 android android無需使用r初始化資源
本文介紹利用反射調用資源和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;@Overrideprotected 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() {@Overridepublic void onClick(View arg0) {Toast.makeText(getApplicationContext(), "HelloWorld",Toast.LENGTH_LONG).show();//字串是控制項的id}});}}
通過Android API 的通過反射擷取id的方法
Context.getResources().getIdentifier("activity_main", "layout", paramContext.getPackageName());
Android 反射調用資源和id