前言

1. 动态加载?

此处的动态加载指的是从服务器或者其他地方获取 jar包,在运行的时候,加载jar包,然后与app中的jar包互相调用,这里为了方便演示效果,直接把 jar包放在 assets目录下,在程序运行的时候直接从 获取assets下边的jar包,来模拟从服务器端获取

2. 动态加载原理?

Android程序是运行在Dalvik/ART 虚拟机中,而 Dalvik/ART 虚拟机执行 dex文件,dex文件是在 打包apk过程会生成,可以把apk后缀改为 zip,然后解压会看到,如下图所示

打包apk之后不能修改里面的 dex文件,我们只能加载外部SD卡的dex文件或者从网络上边下载 dex文件,通过 DexClassLoader或者PathClassLoader这两个类加载器加载 dex文件中的类,通过反射invoke调用dex类中的方法。

这样做的好处是:可以让用户不用卸载、不用重新安装apk,通过替换外部加载的 dex文件,实现动态加载、动态更新apk的目的。

图片.png

3. Dalvik虚拟机类加载机制

Dalvik虚拟机与JVM虚拟机类加载机制一样,都是在运行程序时候首先把对应的类加载到内存中,Dalvik虚拟机不能直接用ClassLoader加载 .dex文件,Android从ClassLoader派生出两个类,DexClassLoader和PathClassLoader,这两个类是我们加载 dex文件的关键,二者区别在于:

DexClassLoader:可以加载jar/apk/dex,可以从SD卡中加载未安装的 apk;

PathClassLoader:只能加载已经安装的 apk文件;

所以,下边我们就采用 DexClassLoader来写一个小的示例代码:动态的加载dex文件中的资源文件(其实就是 dex文件中的一个类Dynamic中的一个 sayHello()方法);

这个实例代码是参照网上一个大神的写的

4. 代码如下

项目目录如下,这里为了演示,直接把 dex文件放到 assets下,来模拟从服务器中下载的插件:

图片.png

1>:MainActivity代码如下:

/**

* Email: 2185134304@qq.com

* Created by Novate 2018/5/11 7:53

* Version 1.0

* Params:

* Description: 点击Button按钮 ,加载dex文件中的 class,并调用其中的 sayHello()方法

*/

public class MainActivity extends AppCompatActivity {

private Dynamic dynamic;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//添加一个点击事件

findViewById(R.id.tx).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

loadDexClass();

}

});

}

/**

* 加载dex文件中的class,并调用其中的sayHello方法

*/

private void loadDexClass() {

File cacheFile = FileUtils.getCacheDir(getApplicationContext());

String internalPath = cacheFile.getAbsolutePath() + File.separator + "dynamic_dex.jar";

File desFile = new File(internalPath);

try {

if (!desFile.exists()) {

desFile.createNewFile();

// 从assets目录下 copy 文件到 app/data/cache目录

FileUtils.copyFiles(this, "dynamic_dex.jar", desFile);

}

} catch (IOException e) {

e.printStackTrace();

}

// 这里由于是加载 jar文件,所以采用DexClassLoader

//下面开始加载dex class

DexClassLoader dexClassLoader = new DexClassLoader(internalPath, cacheFile.getAbsolutePath(), null, getClassLoader());

try {

// 类加载器负责读取 .class文件,并把它转为 Class实例,这个实例就表示一个java类

// 加载 dex文件中的Class,格式是:包名+类名(全类名)

Class libClazz = dexClassLoader.loadClass("wangyang.zun.com.mydexdemo.dynamic.impl.IDynamic");

// 调用Class的 newInstance()方法,创建Class的对象 dynamic

// Dynamic 是 dex文件中之前的一个接口类

dynamic = (Dynamic) libClazz.newInstance();

if (dynamic != null)

Toast.makeText(this, dynamic.sayHelloy(), Toast.LENGTH_LONG).show();

} catch (Exception e) {

e.printStackTrace();

}

}

}

2>:FileUtils工具类如下:

/**

* Email: 2185134304@qq.com

* Created by Novate 2018/5/11 7:53

* Version 1.0

* Params:

* Description: 从assets目录下 copy 文件到 app/data/cache目录

*/

public class FileUtils {

public static void copyFiles(Context context, String fileName, File desFile) {

InputStream in = null;

OutputStream out = null;

try {

in = context.getApplicationContext().getAssets().open(fileName);

out = new FileOutputStream(desFile.getAbsolutePath());

byte[] bytes = new byte[1024];

int i;

while ((i = in.read(bytes)) != -1)

out.write(bytes, 0 , i);

} catch (IOException e) {

e.printStackTrace();

}finally {

try {

if (in != null)

in.close();

if (out != null)

out.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

public static boolean hasExternalStorage() {

return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);

}

/**

* 获取缓存路径

*

* @param context

* @return 返回缓存文件路径

*/

public static File getCacheDir(Context context) {

File cache;

if (hasExternalStorage()) {

cache = context.getExternalCacheDir();

} else {

cache = context.getCacheDir();

}

if (!cache.exists())

cache.mkdirs();

return cache;

}

}

3>:Dynamic接口如下,与 dex文件中类一样:

public interface Dynamic {

String sayHelloy();

}

android novate乱码,Android 动态加载(四) - 简单demo实现相关推荐

  1. android: 静态XML和动态加载XML混合使用,以及重写Layout控件

    近期对android里面控件修改做了很多实验,由于公司需求很多,不得不重写很多控件.程序目标无非是:高效.轻巧.清晰.标准化 完成动态加载Layout有两种方法,依据个人喜好进行选择: 方法1:静态主 ...

  2. Android Trick 3: GridView动态加载数据情况下,选中状态的实现

    GridView使用AdapterView动态加载数据情况下,无论是在onCreate.Onstart.OnResume方法中调用getChildCount()均为0,这说明数据并没有在Activit ...

  3. C#利用反射实现动态加载程序集简单案例

    反射可以不但用来读取元数据,还可以使用反射从编译时还不清楚的类型中动态创建程序集,此案例摘自C#高级编程. 首先先创建一个控制台应用程序,然后添加一个类库,类库名称为CalculatorLib,如下图 ...

  4. Android笔记 fragment入门 动态加载fragment demo+ 判断横竖屏

    代码基本与上一篇blog一样 少量更改 1布局 activity_main.xml <LinearLayout xmlns:android="http://schemas.androi ...

  5. android novate乱码,Android信任指定CA證書+Okhttp+限定https

    以下筆者實測單向驗證可運作(雙向尚未驗證) 安卓指定CA證書步驟: application中加入設定android:networkSecurityConfig 可排除部分僅用http 可排除第三方使用 ...

  6. android novate乱码,Android RxJava+Retrofit2+RxBinding

    Android RxJava+Retrofit2+RxBinding 本文原创,转载请注明出处.欢迎关注我的 简书. 安利一波我写的开发框架:MyScFrame喜欢的话就给个Star 前言: 之前写了 ...

  7. Android apk动态加载机制的研究(二):资源加载和activity生命周期管理

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 为了 ...

  8. Android插件化开发之DexClassLoader动态加载dex、jar小Demo

    一.温故动态加载ClassLoader机制 如果对Android的ClassLoader加载机制不熟悉,猛戳Android插件化开发动态加载基础之ClassLoader工作机制 http://blog ...

  9. Android插件化学习之路(一)之动态加载综述

    前段时间,公司项目完成了插件化的开发,自己也因此学习了很多Android插件化的知识,于是想把这些内容记录下来,本次带来Android插件化的第一篇:动态加载综述 Android插件化学习之路(一)之 ...

最新文章

  1. MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)...
  2. 解决protobuf import路径的问题
  3. python代码写完怎么运行-Python 项目代码写完了,然后怎么打包和发布?
  4. 关于在VS2010中学习c++的MFC
  5. DockerCon SF 18 Day One 速记 - 从容器到云原生
  6. [LeetCode] Palindrome Number Valid Palindrome - 回文系列问题
  7. python scapy sniff timeout_为什么我尝试使用scapy.sniff()函数获取此奇怪的输出,以尝试监听打开的网站的流量?...
  8. python波峰波谷算法_波动均分算法
  9. python幂运算的符号有哪些及画法_SymPy 符号计算基本教程
  10. 创业 7 年最痛教训
  11. matlab中怎样绘制离散点,matlab中怎么绘制大量的离散点
  12. python 随机颜色
  13. 2018年的43个最佳网络监控工具
  14. java生成emf_推荐一款java代码生成的插件EMF
  15. 散列表的概念及其拉链法和常见的散列函数(C语言)
  16. 冰川时代4中英台词全集
  17. 欢迎加入可一科技,见证区块链技术的力量
  18. 关于git reset --hard这个命令的惨痛教训
  19. hihoCoder1378 (最大流最小割)
  20. 计算机桌面个性化怎样设置方法,电脑桌面图标怎么个性化自定义设置呢?

热门文章

  1. 在32位Win7下安装MySQL5.7.10安装配置过程
  2. @Kubernetes(k8s)安装与集群服务部署详解
  3. c# mysql 插入返回id_在C#中,mysql插入一条数据时,怎么同时把这条数据的主键返回?...
  4. 三个圆形按键点击颜色发生改变
  5. 测试not_in_vstar_and_v3(mate)_(e_t)_no_tec_rec
  6. vegan素食认证介绍
  7. 南油 机器人_机器人创客-作文
  8. 基于STM32单片机甲醛二氧化碳温度湿度采集系统
  9. OSpider v3.0.0 开发者手册
  10. 若依框架源码解读之数据源篇