Android动态加载JAR包的实现方法

        有时候我们需要使用动态更新技术,简单来说就是:当我们把开发jar包发送给用户后,如果后期升级了部分代码,这时让用户的jar包自动更新,而不是用户主动手动地去更新的技术就是动态更新。这个需要使用的技术之一就是Android动态加载JAR包。

       主要的过程分为两步,一个是将需要导出的java文件导出位jar包,java文件代码如下所示:

package adapter;

public class RoutePlanManager {
    
    private String name = "RoutePlanManager";
    public static String get() {
        return "hello world";
    }
}

        导出为Hello.jar,这时我们需要使用Android SDK提供的工具(在platform-tools目录下),有些版本的没有,可以网上下载。利用dx工具,将java的jar包转为Android虚拟机可以认识的字节码。具体来说,就是执行如下的命令:

dx --dex --output=dex.jar Hello.jar
其中,Hello.jar是我们的源jar包,dex.jar是我们用dx工具处理后的jar包,是Android虚拟机可以识别的jar文件,接下来就可以进行第二步操作了。
这里,我们需要使用DexClassLoader类实现Jar的动态加载,该类构造方法的官方文档如下所示:

public DexClassLoader (String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)

Added in API level 3
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.

The path lists are separated using the character specified by the path.separator system property, which defaults to :.

Parameters
dexPath	the list of jar/apk files containing classes and resources, delimited by File.pathSeparator, which defaults to ":" on Android
optimizedDirectory	directory where optimized dex files should be written; must not be null
libraryPath	the list of directories containing native libraries, delimited by File.pathSeparator; may be null
parent	the parent class loader
该接口具有四个参数,第一个是dex.jar包的路径,第二个可以认为是挂载路径,就是优化后的dex文件的存放路径,对权限有要求,所以需要通过上下文获取路径,第三个参数设置为null,第四个代表父亲类加载器。

        我们在Android中实现动态加载的代码如下所示:

           String sdcard = Environment.getExternalStorageDirectory().getAbsolutePath();
           String jarPath = sdcard + "/Jar/dex.jar";
           String tmpPath = getApplicationContext().getDir("Jar", 0).getAbsolutePath();
            DexClassLoader cl = new DexClassLoader(jarPath, tmpPath
                    , null, this.getClass().getClassLoader());
            Class libProviderCls = null;
            try {
                  libProviderCls = cl.loadClass("adapter.RoutePlanManager");
                  Constructor localConstructor = libProviderCls.getConstructor(new Class[] {});
                  Object obj = localConstructor.newInstance(new Object[] {});
                  Method mMethodWrite = libProviderCls.getDeclaredMethod("get");
                  mMethodWrite.setAccessible(true);
                  String str = (String) mMethodWrite.invoke(obj);
                  Toast.makeText(LoadJarActivity.this, str, Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                e.printStackTrace();
            }
当加载了Jar包之后,我们需要执行Jar包中的方法,这个时候我们需要使用Java的反射来处理。以上就是实现动态加载的方式。



你可能感兴趣的:(Java,Android,学习笔记)