目的:
目前工程项目过多,但是大部分基础功能模块和工具模块都是一样的,为了避免重复造轮子,所以需要开发一个library供其他项目调用。但是问题出来了,有些比较关键的业务逻辑又不想开源给其他用户知道,这个时候就需要开发一个隐藏源代码的library的工程了。
做法:
首先需要了解一个函数。
Context.getResources().getIdentifier(String name,String type,String packageName);
这个函数用来找到某个res下的某个文件夹的某个资源的id。
因为我们需要隐藏源代码,所以源代码需要以jar包的形式来打入library包里面,如果用工程里面的R.string.xxxx来获取某个资源的id,肯定是没办法获取正确的。
所以原来的代码
textView1.setText(R.string.test);
变成了
textView1.setText(con.getResources().getIdentifier("test","string",con.getPackageName()));
当然,还可以使用反射的方法来实现这个功能。
Field field = R.layout.class.getField("layout_test"); int i = field.getInt(new R.layout()); return i;
推荐使用第一种方法getIdentifier来实现这个功能。
具体实现方法为:
1.开发library工程还是按照之前的开发方式来开发,也就是建立一个library的android的工程,然后对于所有R.xx.xxx的情况,全部转换成之前所说的getIdentifier()方法来获取id设置对应的值。
2.之后将bin文件夹内的xxxlibrary.jar包拷贝出来(注意必须是运行过一次之后最近的jar包),拷贝到另外一个空的library的android工程的libs中。
3.然后将之前的library工程里面的所有资源文件和用到的jar包都拷贝到后面新建的那个空的library的android工程中。
4.使用切换下对应测试工程所引入的library工程即可。
但是还得要说明一个问题,对于styleable的资源id获取,往往出现在自定义控件的时候。采用getIdentifier()来获取的话会发现所有获取的id都为0.而且R.styleable.xxx有可能返回的不是int而是int的数组
于是对于这种情况,必须得采用反射来获取
/**
* 对于context.getResources().getIdentifier无法获取的数据,或者数组
* 资源反射值
* @paramcontext
* @param name
* @param type
* @return
*/
private static Object getResourceId(Context context,String name, String type) {
String className = context.getPackageName() +".R";
try {
Class<?> cls = Class.forName(className);
for (Class<?> childClass : cls.getClasses()) {
String simple = childClass.getSimpleName();
if (simple.equals(type)) {
for (Field field : childClass.getFields()) {
String fieldName = field.getName();
if (fieldName.equals(name)) {
System.out.println(fieldName);
return field.get(null);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
*context.getResources().getIdentifier无法获取到styleable的数据
* @paramcontext
* @param name
* @return
*/
public static int getStyleable(Context context, Stringname) {
return ((Integer)getResourceId(context, name,"styleable")).intValue();
}
/**
* 获取styleable的ID号数组
* @paramcontext
* @param name
* @return
*/
public static int[] getStyleableArray(Context context,String name) {
return (int[])getResourceId(context, name,"styleable");
}
而且还需要注意 对应的xml里面定义使用自定义控件的时候,需要设置的是
xmlns:test="http://schemas.android.com/apk/res/res-auto"
参考博客
http://blog.csdn.net/xcookies/article/details/41154927
http://ryeeeeee.com/2014/07/20/How-to-Create-Android-Library-Project.html