java dexclassloader_DexClassLoader使用-(1)

可以先参考java的java类加载器。

一、DexClassLoader

一般情况下,我们使用import就可以了,为什么还要使用类装载器呢?

import中所引用的类文件有两个特点:

1.一定在存在于本地,当程序运行时需要这个类时,内部类装载器就会自动装载,程序员感知不到这个过程。

2.编译时一定要在现场,否则会因找不到引用文件而不能正常编译。

但是在有的情况下,要用的类不一定满足这些条件,如从运程下载一个类并在本地运行,例子如applet执行的java,另一种是要引用的class文件不方便在编译时直接参与 ,而只能在运行时动态调用。如在android中修改FrameWork中已经有的类,为了保持与原生的FrameWork最小化的修改,可以使用类装载器动态装载自己定义 的jar包。

二、DexClassLoader的使用方法

有两个apk。

插件部分

定义了类PluginClass。如下

public class PluginClass {

public PluginClass(){

Log.d("PluginCLass", "PluginClass initiazed");

}

public int function1(int a,int b){

return a +b;

}

}

还定义了

一个空的Activity,这个作用只是为了让宿主apk中可以找到package而已,所以只要有就可以了。

android:name=".BlankActivity"

android:label="@string/title_activity_blank" >

我们将可以通过intent-filter得到相关的信息。

宿主部分

通过下面的ClassLoader可以装载插件中的类,再构造出Method对象 ,并构造出Method对象所使用的参数对象 ,然后才能调用 。

ublic void useDexClassLoader(){

Intent intent = new Intent("com.example.lsj.testapp.plugin.client", null);

PackageManager pm = getPackageManager();

final List plugins = pm.queryIntentActivities(intent, 0);

ResolveInfo rinfo = plugins.get(0);

ActivityInfo ainfo = rinfo.activityInfo;

String div = System.getProperty("path.separator");

String packageName = ainfo.packageName;

String dexPath = ainfo.applicationInfo.sourceDir;

String dexOutputDir = getApplicationInfo().dataDir;

String libPath = ainfo.applicationInfo.nativeLibraryDir;

DexClassLoader dexClassLoader = new DexClassLoader(dexPath,

dexOutputDir,libPath,this.getClass().getClassLoader());

try{

Class > clazz = dexClassLoader.loadClass(packageName+".PluginClass");

Object obj = clazz.newInstance() ;

Class [] params = new Class[2];

params[0]= Integer.TYPE;

params[1] = Integer.TYPE ;

Method action = clazz.getMethod("function1", params) ;

Integer ret = (Integer)action.invoke(obj, 1,2);

Log.e(TAG, "return value is :"+ ret);

}catch ( ClassNotFoundException e){

}catch (InstantiationException e2 ){

}catch (IllegalAccessException e3){

}catch (NoSuchMethodException e4){

}catch (InvocationTargetException e5){

}

}

DexClassLoader方法参数:

dexPath:目标所在的apk或者jar文件的路径,装载器将从路径中寻找指定的目标类。

dexOutputDir:由于dex 文件在APK或者 jar文件中,所以在装载前面前先要从里面解压出dex文件,这个路径就是dex文件存放的路径,在 android系统中,一个应用程序对应一个linux用户id ,应用程序只对自己的数据目录有写的权限,所以我们存放在这个路径中。

libPath :目标类中使用的C/C++库。

最后一个参数是该装载器的父装载器,一般为当前执行类的装载器。

这里我们得到的Class对象是CLassLoader可以识别的类,而PluginClass是程序执行后可以识别的类,此时仅仅装载了PluginClass的程序代码,还没有创建出其对象 ,接下来可以使用Class.newInsance()方法来调用PluginClass类的构造方法,并返回一个真正的PluginClass对象。

但是我们不能直接去调用 PluginClass的任何方法,只能通过反射去调用其方法。

反射机制时主要使用了Method类,Class对象的getMethod()方法可以返回这个类中任何方法,getMethod()有两个参数 ,一个是要访问的函数名,另一个是函数的参数类型。

得到目标类的Method对象后,就可以调用Method对象的invoke方法,这个方法的第一个参数是执行目标函数的对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值