1. 程式人生 > >Android專案,library中根據資源id獲取資源

Android專案,library中根據資源id獲取資源

場景

   

BaseActivity放在library中,所有頁面都有一個返回按鈕,id為id_iv_back。想在BaseActivity統一設定返回點選事件。但是library無法獲取app的R檔案,也就無法獲取該引用資源。。。

解決方法

所以我們必須實時的獲取這個十六進位制的數值。有兩個方式可以選擇:

1.(推薦)通過android.content.res.Resources類的

int getIdentifier(String name, String defType, String defPackage) . 比如,我們需要在Activity中設定佈局,我們要得到res/layout/目錄下的 “main_layout.xml” 佈局檔案的ID.
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        int id = getResources().getIdentifier(“main_layout“, "layout", getPackageName());
        setContentView(id);
        ...
    }

2.使用Java語言的反射機制。但是使用反射畢竟麻煩。

    Field field = R.layout.class.getField("main_layout");
    int i = field.getInt(new R.layout());
    return i;

封裝:

閱讀騰訊TIM的demo程式碼時候發現了該封裝方法。

/**
 * 根據資源的名字獲取其ID值
 * */
public class MResource {

	public static int getIdByName(Context context, String className, String name) {
		String packageName = context.getPackageName();
		Class r = null;
		int id = 0;

		try {
			r = Class.forName(packageName + ".R");
			Class[] classes = r.getClasses();
			Class desireClass = null;

			for (int i = 0; i < classes.length; ++i) {
				if (classes[i].getName().split("\\$")[1].equals(className)) {
					desireClass = classes[i];
					break;
				}
			}

			if (desireClass != null) {
				id = desireClass.getField(name).getInt(desireClass);
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}

		return id;
	}

	public static int[] getIdsByName(Context context, String className, String name) {
		String packageName = context.getPackageName();
		Class r = null;
		int[] ids = null;

		try {
			r = Class.forName(packageName + ".R");

			Class[] classes = r.getClasses();
			Class desireClass = null;

			for (int i = 0; i < classes.length; ++i) {
				if (classes[i].getName().split("\\$")[1].equals(className)) {
					desireClass = classes[i];
					break;
				}
			}

			if ((desireClass != null) && (desireClass.getField(name).get(desireClass)) != null && (desireClass.getField(name).get(desireClass).getClass().isArray())) {
				ids = (int[]) desireClass.getField(name).get(desireClass);
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}

		return ids;
	}
}

在BaseActivity中
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutResID());
        
        if (null != findViewById(MResource.getIdByName(getApplication(), "id", "id_iv_back"))) {
            findViewById(MResource.getIdByName(getApplication(), "id", "id_iv_back")).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finish();
                }
            });
        }
}