需要动态加载一个jar包,然后一直报Class not found的错误,仔细阅读了博客,发现没有对jar进行处理,
需要使用dx命令对jar进行处理;

dx --dex --output=Loader_dex.jar Loader.jar

下面大体梳理一下动态加载jar的流程

1 jar包的制作

代码写完后,对项目进行打包就行。比较简单。

2 处理jar

使用dx命令处理jar

dx --dex --output=Loader_dex.jar Loader.jar

dx命令在Android SDK下,比如我电脑的dx文件路径为:sdk/build-tools/27.0.2/dx

3 加载jar

直接上代码

private void loadJar(){
       File dexoutputdir = getDir("dex1",0);
       String dexPath = Environment.getExternalStorageDirectory().toString() + File.separator + "Loader_dex.jar";
       DexClassLoader loader = new DexClassLoader(dexPath,dexoutputdir.getAbsolutePath(),null,getClassLoader());
       
       try {
           Class clz = loader.loadClass("com.example.interf.JarLoader");
           ILoader iShowToast = (ILoader) clz.newInstance();
           Toast.makeText(this,iShowToast.sayHi(),Toast.LENGTH_LONG).show();
       } catch (Exception e){
            Log.d("dd",e.toString());
       }
   }

dexPath、 dexoutputdir尽量放到APP目录下。

此处需要注意DexClassLoader的四个参数:

  • 参数1 dexPath:待加载的dex文件路径,如果是外存路径,一定要加上读外存文件的权限( ),否则会报与报错,Android4.4 KitKat及以后的版本需要此权限,之前的版本不需要该权限。
  • 参数2 optimizedDirectory:解压后的dex存放位置,此位置一定要是可读写且仅该应用可读写(安全性考虑),所以只能放在data/data下。本文getDir(“dex1”, 0)会在/data/data/**package/下创建一个名叫”app_dex1“的文件夹,其内存放的文件是自动生成Loader_dex.dex;需要注意,data/data文件夹只有在手机root之后,才看得到。
  • 参数3 libraryPath:指向包含本地库(so)的文件夹路径,可以设为null。
  • 参数4 parent:父级类加载器,一般可以通过Context.getClassLoader获取到,也可以通过ClassLoader.getSystemClassLoader()取到。

参考

【Android】Android动态加载Jar、APK的实现