android项目中的res目录下的资源会以int形式存放到R.java,Java/Kotlin调用时会往往会采用R.string.appname这样的方式。
但是在封装aar对外使用时需要考虑接入方编译器无法依赖aar,需要拆解成jar来使用的情况。比如游戏SDK。这个时候会有找不到资源文件的异常,可在封装时Java/Kotlin使用到R文件时使用getIdentifier方法来获取,值得注意的是无法通过getIdentifier获取declare-styleable,需要反射 。
/**
* @param name 资源名称
* @param defType 资源类型
* @param defPackage 包名
*/
context.getResources().getIdentifier(String name, String defType, String defPackage)
如
R.string.appname
替换为
context.getResources().getIdentifier(
"appname",
"string",
context.getPackageName())
R.id.tv
替换为
context.getResources().getIdentifier(
"tv",
"id",
context.getPackageName())
在此封装成一个工具类方便调用,值得注意的是无法获取declare-styleable,需要通过反射来读取xml设置控件属性的declare-styleable
import android.content.Context;
import android.content.res.Resources;
import java.lang.reflect.Field;
public class FreeCityResourcesUtil {
private static Resources res;
private static String packetName;
public static void init(Context context){
res = context.getResources();
packetName = context.getPackageName();
}
private static int getIdentifier(String name, String type){
return res.getIdentifier(name, type, packetName);
}
public static int getLayout(String name){
return getIdentifier(name, "layout");
}
public static int getString(String name){
return getIdentifier(name, "string");
}
public static int getId(String name){
return getIdentifier(name, "id");
}
public static int getColor(String name){
return getIdentifier(name, "color");
}
public static int getDrawable(String name){
return getIdentifier(name, "drawable");
}
public static int getStyle(String name){
return getIdentifier(name, "style");
}
/**
* 因无法使用getIdentifier来获取int[],通过反射来读取xml设置控件属性的declare-styleable
*/
public static int[] getStyleables(String name){
try {
Field[] fields = Class.forName(packetName + ".R$styleable" ).getFields();
for (Field f : fields ){
if (f.getName().equals(name)){
int[] ret = (int[])f.get(null);
return ret;
}
}
}
catch (Throwable t){
}
return null;
}
/**
* 因无法使用getIdentifier来识别declare-styleable的attr,通过反射来读取xml设置控件属性的declare-styleable的attr
*/
public static int getStyleable(String name){
try {
Field fields2 = Class.forName(packetName + ".R$styleable" ).getField(name);
return (int)fields2.get(null);
}
catch (Throwable t){
}
return 0;
}
public static int getDimen(String name){
return getIdentifier(name, "dimen");
}
}