android动态加载jar

在android中,有一个自己的类加载器,那就是DexClassLoader.这个可以加载jar/apk/dex,也可以从SD卡中加载,也是本文的重点。需要注意的是,通过ide生成的jar包,需要进入dx处理,动态加载之后才会成功,否则将会失败。

首先,我们先建立一个工程。工程中,将动态加载jar文件,然后通过反射来调用jar包中的方法。代码很简单

     File file = new File("/storage/sdcard0/liuhang123/testdex.jar");  
     final File optimizedDexOutputPath = getDir("temp", Context.MODE_PRIVATE);
     String filePath = file.getAbsolutePath();
     String optimizedPath = optimizedDexOutputPath.getAbsolutePath();
     DexClassLoader classLoader = new DexClassLoader(file.getAbsolutePath(),  
             optimizedDexOutputPath.getAbsolutePath(), null,  
             getClassLoader());  
     try {  
         Class<?> iclass = classLoader.loadClass("com.ycl.lib.IClass");
         Constructor<?> istructor = iclass.getConstructor(Context.class);  
         //利用反射原理去调用   
         Method method = iclass.getMethod("call", new  Class[ 0 ]);
         method.invoke(istructor.newInstance(this), new  Object[]{});
Method method1 = iclass.getMethod("getData",new Class[0]);
String data = (String) method1.invoke(istructor.newInstance(this),new Object[]{});
         System.out.println(data);  
     } catch (Exception e) {  
         // TODO Auto-generated catch block   
         e.printStackTrace();  
     }  

找到对应jar文件的路径,然后新建一个app私有目录存放jar文件。然后初始化dexclassloader加载jar文件。对应的加载代码就是

DexClassLoader classLoader = new DexClassLoader(file.getAbsolutePath(),  
             optimizedDexOutputPath.getAbsolutePath(), null,  
             getClassLoader());
 

DexClassLoader具体参数

public DexClassLoader (String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)
Creates a DexClassLoader that finds interpreted and native code. Interpreted classes are found in a set of DEX files contained in Jar or APK files.
Parameters

dexPath 需要装载的APK或者Jar文件的路径。
optimizedDirectory 优化后的dex文件存放目录,不能为null
libraryPath 目标类中使用的C/C++库的列表,每个目录用File.pathSeparator间隔开; 可以为 null
parent 该类装载器的父装载器,一般用当前执行类的装载器

创建一个DexClassLoader用来找出指定的类和本地代码(c/c++代码)。用来解释执行在DEX文件中的class文件。


加载jar之后,就可以通过反射调用jar中的方法了。

try {  
         Class<?> iclass = classLoader.loadClass("com.ycl.lib.IClass");
         Constructor<?> istructor = iclass.getConstructor(Context.class);  
         //利用反射原理去调用
//加载call方法
         Method method = iclass.getMethod("call", new  Class[ 0 ]);
//调用call方法
         method.invoke(istructor.newInstance(this), new  Object[]{});
//加载getData方法
Method method1 = iclass.getMethod("getData",new Class[0]);
//调用getData方法
String data = (String) method1.invoke(istructor.newInstance(this),new Object[]{});
         System.out.println(data);  
     } catch (Exception e) {  
         // TODO Auto-generated catch block   
         e.printStackTrace();  
     }  


2.创建库文件,也就是jar包的源代码。我们只需要在原来的工程中,新建一个android library moudle。目录如下,包含了一个接口和他的实现类


实现类代码如下:

public class IClass implements Iinterface {  
  
    private Context context;  
  
    public IClass(Context context) {  
        super();  
        this.context = context;  
    }  
  
    @Override  
    public void call() {  
        Toast.makeText(context, "call method haha", Toast.LENGTH_SHORT).show();
    }  
  
    @Override  
    public String getData() {  
        return "hello,i am from IClass aa";
    }  
  
} 

这样library就好了,build一下,在build目录下面生成了对应的jar文件。

当然,如果你需要指定jar文件生成的目录,可以修改library模块的build.gradle文件,在文件中加入

//Copy类型,把library编译成jar包,并导出到build/libs/目录下面
task makeJar(type: Copy) {
    //删除存在的
    delete 'build/libs/mysdk.jar'
    //设置拷贝的文件
    from('build/intermediates/bundles/release/')
    //打进jar包后的文件目录
    into('build/libs/')
    //将classes.jar放入build/libs/目录下
    //include ,exclude参数来设置过滤
    //(我们只关心classes.jar这个文件)
    include('classes.jar')
    //重命名
    rename ('classes.jar', 'classes.jar')
}
makeJar.dependsOn(build)

然后在android studio 命令行执行  gradlew makeJar,执行成功之后,会在build/libs/目录下面生成classes.jar

然后我们把这classes.jar文件复制出来。使用dx工具生成dexclassloader能够使用的jar文件。在你的android sdk对应目录C:\Users\chengliang.yu\AppData\Local\Android\sdk\build-tools\25.0.2   build-tools下面有一个androidbuild-tools版本文件夹,随便进去一个,下面有个dx.bat

没有配置环境变量就通过命令行进入该目录,然后使用dx 命令生成新的jar文件,对应命令如下

dx --dex --output=d:\test\testdex.jar classes.jar   d:\test\testdex.jar对应了生成的新的jar文件对应的目录    ,后面classes.jar就是library模块生成的jar文件

然后我们把生成的testdex.jar文件放入要使用的工程,动态加载,然后反射就可以使用jar文件中的方法了。


demo下载地址:链接:http://pan.baidu.com/s/1bWge5K 密码:d6yb





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值