android|android 动态加载技术demo

1.引言 前面写了很多关于java类加载机制的笔记。今天又看了下android动态加载,发现和java加载类真是贴切,因此看了很顺畅,故而按照博客的指示写了一个小demo,再次记录下。
2.正题 【android|android 动态加载技术demo】动态加载技术,因为使用到的类是外来的类,主app中没得这个类。因此无法在主app中事先引用进来。所以反射是我们经常想到的解决办法,博客也提出了接口的方法。也对反射的确是有点慢。
动态加载访问api:1.反射 2.接口。
回顾前面的jvm加载类的过程我们知道classloader,通过调研loadClass,进而继续调用findClass,然后findClass 在调用defineClass。最终可以在jvm的堆中形成Class对象。。而Android的dvm中并没得defineClass,它有前俩步骤,但是没得defineClass的过程,dvm是将class文件,直接打包成dex文件。当运行代码的时候发现要用到某一个Class文件。dvm会在dex找到对应的Class文件,然后通过加载器将dex 转换成Class对象。
实验:用接口的方式实现动态加载技术。 2.1.定义接口,定义实现类。 android|android 动态加载技术demo
文章图片
Paste_Image.png 将Dynamic类打包成jar包的时候,折腾了一番。发现网上打包成jar的都额外的建立了一个Module。然后设置task makeJar。我按照网上的教程没实践成功,最后把Class.jar 拿出来,然后通过删除 保留我想要的。
将Dynamic 和IDynamic 分别打包成Dynamic.jar 和 IDynamic.jar .
前面说过dvm只认识dex文件。所以我们将Dynamic.jar 进一步转换成DynamicDex.jar。用到的工具是sdk,plateform-tool的dx 工具。执行

dx --dex --output=dynamic_temp.jar(输出的名字)dynamic.jar(最开始的名字)

在同一个文件夹下可以这样,不同的话要带上路径
然后将IDynamic.jar 以第三方jar形式导入到项目中。
前期准备工作就是这些。。
2.2.加载外来的类 DexClassLoader 和PathClassLoader的区别是,DexClassLoader能加载外来的没有安装的apk,jar。 而PathClassLoader只能加载已经安装的。
因此选择DexClassLoader作为类加载器。
DexClassLoader:
DexClassLoader dexClassLoader=new DexClassLoader(outDexJar,appFiles,null,getClassLoader());

outDexJar参数: 外来的apk,jar的文件路径。
appFiles:app的包名下面的Files文件夹。通过以下代码获取
getApplicationContext().getFilesDir().getAbsolutePath(); //app的包名下面的Files文件夹 getApplicationContext().getCacheDir().getAbsolutePath(); //app包名下面的Caches文件夹 ```java public class MainActivity extends AppCompatActivity{ privateIDynamic iDynamic; Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button= (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String outDexJar= Environment.getExternalStorageDirectory().getAbsolutePath()+"/test"+"/Dynamic.jar"; File f=new File(outDexJar); if (f.exists()){ String ss="123"; } String appFiles=getApplicationContext().getCacheDir().getAbsolutePath(); ClassLoader classLoader=getClassLoader(); String classloadName=classLoader.toString(); DexClassLoader dexClassLoader=new DexClassLoader(outDexJar,appFiles,null,getClassLoader()); try { Class c=dexClassLoader.loadClass("xinyi.com.mylibrary.Dynamic"); //通过loadClass,找到dex对应的Class,然后变成Class try { iDynamic= (IDynamic) c.newInstance(); Toast.makeText(MainActivity.this,iDynamic.helloWorld(), Toast.LENGTH_SHORT).show(); ; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }); } }

好了这个demo很简单。不过我在写博客的过程中,想到一个问题。通过类加载器将Class文件----->dex 文件。然后在使用的过程中又是将dex文件转化成Class文件。这不是多此一举吗? 当然肯定不是多此一举,dex文件必然有一些好处。下一篇 记录下dex的优点,以及dex文件的文件格式。

    推荐阅读