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.定义接口,定义实现类。
文章图片
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文件的文件格式。
推荐阅读
- Android源码探究(Android|Android源码探究:Android Java层消息机制完全解析)
- Android手机上Webview页面以及微信/QQ浏览器真机调试
- #|第9章 类加载及执行子系统的案例与实战
- vue.js|加载页面全局设置spinning
- Vue动态数据实现|Vue动态数据实现 el-select 多级联动、数据回显方式
- Android应用隐私合规检测实现方案详解
- 将android的短信导入iphone|将android的短信导入iphone 数据库sms.db 方法 及iphone 忘记访问限制密码时最高效的解决方法
- android开发笔记
- Android|Android 常用正则表达式
- Android加载长图