最近在看一些android插件化方面的代码,一般都会用到java最基本的反射功能。原来也大概知道怎么用,但是一直没有系统的整理和实践过。借此机会,将基本的反射总结记录一下
Android的ClassLoader的结构
DexClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)
dexPath the list of jar/apk files containing classes and resources ----- apk、jar包或者解压后的apk所在的路径,不能为空
optimizedDirectory directory where optimized dex files should be written; must not be null------解压后的dex文件存放的路径,不能为空,一般都放在程序的私有目录,防止恶意代码的注入
libraryPath the list of directories containing native libraries; may be null------so库存在的目录
parent the parent class loader ----- 父加载器
反射基础:
DynamicTest类,举例
public class DynamicTest implements IDynamic{
public DynamicTest() {
// TODO Auto-generated constructor stub
Log.e("kaka", "DynamicTest init");
}
public DynamicTest(String word){
Log.e("kaka", "DynamicTest init " + word);
}
@Override
public String helloWorld(String word) {
// TODO Auto-generated method stub
return "hello " + word;
}
protected String helloWorld() {
// TODO Auto-generated method stub
return "hello ";
}
private String helloWorld(String word,int index) {
// TODO Auto-generated method stub
return "hello " + word + index;
}
public static String helloWorld(String word){
return "static " + word;
}
}
构造函数
DexClassLoader mClassLoader = new DexClassLoader(optimizedDexOutputPath.getAbsolutePath(),getApplication().getCacheDir().toString(),null,getClassLoader());
Class libClass = mClassLoader.loadClass("com.example.DynamicTest");
带参数的构造函数
Constructor constructor = libClass.getConstructor(String.class);
Object instance = constructor.newInstance("constructort");
私有方法
Method simpleMethod = libClass.getDeclaredMethod("helloWorld");
simpleMethod.setAccessible(true); //私有方法需要设置为true,才能调用
String str = (String)simpleMethod.invoke(instance,"haha");
带参数的方法
Class[] param = new Class[1];
param[0] = String.class;
Method simpleMethod = libClass.getDeclaredMethod("helloWorld",param); //带参数的方法
静态方法
Method method = libClass.getDeclaredMethod("staticString",String.class); //通过class类直接获取静态方法
Log.e("kaka",(String) method.invoke(null,"kaka")); //静态方法,不用传实例对象,直接传null
以上只是简单介绍了基本的用法,其中其他获取Field(成员)的方法都差不多。