Android开发之SDK开发获取资源id报错的问题

我们在开发SDK的时候有时候需要兼容Eclipse版本和AS版本,AS版本就不说了没多大问题,主要是Eclipse版本会有问题。当开发之使用Eclipse开发的时候接入jar包(AS打包成aar,解压获取Jar)的时候会报错资源id找不到,这是因为aar里面的资源id生成了唯一的int值,但是单独将aar解压拿出jar,去找id的值的时候会找不到的,解决办法有:

利用反射:工具类已封装好

package com.mchsdk.paysdk.utils;


import android.content.Context;
import android.content.res.Resources;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;

public class MCHInflaterUtils {

	private static final String TAG = "MCHInflaterUtils";

	/**
	 * 获取布局文件
	 *
	 * @param con
	 *            上下文
	 * @param layoutName
	 *            布局文件名称
	 * @return
	 */
	public static int getLayout(Context con, String layoutName) {
		return getIdByName(con, "layout", layoutName);
	}

	/**
	 * 获取控件
	 *
	 * @param con
	 *            上下文
	 * @param controlName
	 *            控件名称
	 * @return
	 */
	public static int getControl(Context con, String controlName) {
		return getIdByName(con, "id", controlName);
	}

	/**
	 * 获取资源文件
	 *
	 * @param con
	 *            上下文
	 * @param drawableName
	 *            资源名称
	 * @return
	 */
	public static int getDrawable(Context con, String drawableName) {
		return getIdByName(con, "drawable", drawableName);
	}

	/**
	 * Refer to external project resources
	 *
	 * @param context
	 * @param className
	 * @param name
	 * @return
	 */
	private static int getIdByName1(Context context, String className,
			String name) {
		String packageName = null;
		Class<?> r = null;
		int id = 0;
		try {
			packageName = context.getPackageName();
			//MCLog.w(TAG, "packageName:"+packageName);
			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) {
			System.out.println("getIdByName1 ClassNotFoundException");
		} catch (IllegalArgumentException e) {
			System.out.println("getIdByName1 IllegalArgumentException");
		} catch (SecurityException e) {
			System.out.println("getIdByName1 SecurityException");
		} catch (IllegalAccessException e) {
			System.out.println("getIdByName1 IllegalAccessException");
		} catch (NoSuchFieldException e) {
			System.out.println("getIdByName1 NoSuchFieldException");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return id;
	}

	private static int getIdByName2(Context context, String className,
			String name) {
		Resources res = null;
		int id = 0;
		try {
			res = context.getResources();
			id = res.getIdentifier(name, className, context.getPackageName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return id;
	}

	/**
	 *
	 * @param context
	 *            上下文
	 * @param className
	 *            类名
	 * @param name
	 *            属性名
	 * @return
	 */
	public static int getIdByName(Context context, String className, String name) {
		int id = -1;
		int id1 = getIdByName1(context, className, name);
		int id2 = getIdByName2(context, className, name);
		if (id2 != 1 && id2 != 0) {
			id = id2;
		}else if (id1 != 0) {
			id = id1;
		}else {
			MCLog.e(TAG, "存在SDK找不到的资源文件:"+"className:"+className+";   name:"+name);
		}
		return id;
	}

	public static int[] getStyleableIntArray(Context context, String name) {
		try {
			Field[] fields = Class.forName(context.getPackageName() + ".R$styleable").getFields();//.与$ difference,$表示R的子类
			for (Field field : fields) {
				if (field.getName().equals(name)) {
					int ret[] = (int[]) field.get(null);
					return ret;
				}
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}


	/**
	 * 遍历R类得到styleable数组资源下的子资源,1.先找到R类下的styleable子类,2.遍历styleable类获得字段值
	 *
	 * @param context
	 * @param styleableName
	 * @param styleableFieldName
	 * @return
	 */
	public static int getStyleableFieldId(Context context, String styleableName, String styleableFieldName) {
		String className = context.getPackageName() + ".R";
		String type = "styleable";
		String name = styleableName + "_" + styleableFieldName;
		try {
			Class<?> cla = Class.forName(className);
			for (Class<?> childClass : cla.getClasses()) {
				String simpleName = childClass.getSimpleName();
				if (simpleName.equals(type)) {
					for (Field field : childClass.getFields()) {
						String fieldName = field.getName();
						if (fieldName.equals(name)) {
							return (int) field.get(null);
						}
					}
				}
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return 0;
	}




	/**
	 *
	 * @param context
	 * @param type
	 * @param name
	 * @return
	 */
	public static Object getResourceData(Context context, String type, String name) {
		try {
			Class<?> arrayClass = getResourceClass(context, type).getClass();
			Field intField = arrayClass.getField(name);
			return intField.get(arrayClass);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private static HashMap<String, Object> ResourceClass = new HashMap<String, Object>();

	private static Object getResourceClass(Context context, String type) {
		if (ResourceClass.containsKey(type)) {
			return ResourceClass.get(type);
		} else {
			try {
				Class<?> resource = Class.forName(context.getPackageName() + ".R");
				Class<?>[] classes = resource.getClasses();
				for (Class<?> c : classes) {
					int i = c.getModifiers();
					String className = c.getName();
					String s = Modifier.toString(i);
					if (s.contains("static") && className.contains(type)) {
						ResourceClass.put(type, c.getConstructor().newInstance());
						return ResourceClass.get(type);
					} else {
						continue;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}
}

调用方法如下:

设置布局
 setContentView(MCHInflaterUtils.getLayout(ToCertificateActivity.this, "activity_mch_certificate"));
获取id
 TextView txtTitle = (TextView) findViewById(MCHInflaterUtils
                .getControl(this, "tv_mch_header_title"));
获取drawable
MCHInflaterUtils.getDrawable(activity, "normal_login_bt_bg")

猜你喜欢

转载自blog.csdn.net/xiayiye5/article/details/108739727