Android程序运行中动态加载Lib的方法

这两天研究android的动态加载,下面把心得和大家分享一下吧!
 
首先上一个实例:
 
这个是stackOverFlow上面的一个帖子,被采纳的答案解决了这个问题:
 
http://stackoverflow.com/questions/6857807/is-it-possible-to-dynamically-load-a-library-at-runtime-from-an-android-applicat
 
简单翻译一下:
 
第一步:
建一个普通的android项目,里面添加一个类:

01. package org.shlublu.android.sandbox;
02. import android.util.Log;
03. publicclassMyClass{
04. publicMyClass(){
05. Log.d(MyClass.class.getName(),"MyClass: constructor called.");
06. }
07. public void doSomething(){
08. Log.d(MyClass.class.getName(),"MyClass: doSomething() called.");
09. }
10. }
第二步:
把这个android项目导出为apk (当然也可以打成jar包,如果打成jar包,那么jar包里面必须包含classes.dex,这个classes.dex里面包含了上面的MyClass类)
 
第三步:
新建一个android项目(或者用刚刚那个也行)
在里面添加这样一个activity:

01. public class Main extends Activity
02. {@SuppressWarnings("unchecked")
03. @Override
04. protected void onCreate(Bundle savedInstanceState){
05. super.onCreate(savedInstanceState);
06. setContentView(R.layout.main);
07. try{
08. final String libPath =Environment.getExternalStorageDirectory()+"/shlublu.jar";
09. final File tmpDir = getDir("dex",0);
10. final DexClassLoader classloader =newDexClassLoader(libPath, tmpDir.getAbsolutePath(),null,this.getClass().getClassLoader());
11. final Class<Object> classToLoad =(Class<Object>) classloader.loadClass("org.shlublu.android.sandbox.MyClass");
12. final Object myInstance  = classToLoad.newInstance();
13. final Method doSomething = classToLoad.getMethod("doSomething");
14. doSomething.invoke(myInstance);
15. }catch(Exception e){
16. e.printStackTrace();
17. }
18. }
19. }

 

第四步:
跑起来,进入上面的Main
查看Log看结果,是不是发现log里面已经有了我们刚刚第一步添加的MyClass中的方法了?

其实内容并不是很多,看代码基本上就可以看得懂。用到了一个类:
DexClassLoader. 这个类的功能是寻找apk, jar, zip等压缩包里面的classes.dex文件。并把它加载到classloader对象中。然后调用的时候,利用java类的反射功能就可以实现了。
 
我对java研究的比较少,略有知道java里面也有一个classLoader的类,在android中的classloader类是
 
BaseDexClassLoader, 它有两个派生类:
 
PathClassLoader和
DexClassLoader
 
这两个类有何区别?除了用法上的不同(可以见其构造方法),主要是适用范围不同:
PathClassLoader适用于那些已经安装好的apk包。在前面的博文
什么是 Android中的odex和deodex
中已经提到了一个目录,/data/dalvik-cache,这个目录里面包含了所有安卓已经安装的classes.dex文件。因此,如果使用PathClassLoader来加载类,最后加载完的类都会存在这个文件夹里面。
 
而DexClassLoader则不会存在/data/dalvik-cache文件夹里面,而是你指定的一个地方保存。
 
区别就产生在这里:/data/dalvik-cache是系统默认的classes.dex保存位置,而且普通用户没有读写权限,因此如果一个未安装的apk文件使用PathClassLoader来加载的话,没有权限把加载过后的类写到/data/dalvik-cache中去,因此当系统去这个文件夹寻找的时候,就找不到这个类了。而对于已经安装过的apk文件,在/data/dalvik-cache文件夹中有对应的classes.dex文件,所以PathClassLoader可以读写。我试过,如果在已经root的手机上改变/data/dalvik-cache的权限:
adb shell
su chmod 777 /data/dalvik-cache
那么这个时候,PathClassLoader也可以用来加载未安装的apk文件。但是普通用户不可能去改变这个权限的,因此,对于未安装的apk只能用DexClassLoader来安装。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值