[转载] Android动态加载Dex机制解析
本文转载自: http://blog.csdn.net/wy353208214/article/details/50859422
1.什么是类加载器?
类加载器(class loader)是 Java™中的一个很重要的概念。类加载器负责加载 Java 类的字节代码到 Java 虚拟机中。
Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成java.lang.Class类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance()方法就可以创建出该类的一个对象。实际的情况可能更加复杂,比如 Java 字节代码可能是通过工具动态生成的,也可能是通过网络下载的。
基本上所有的类加载器都是 java.lang.ClassLoader类的一个实例,需要了解ClassLoader可以参考这篇文章深入ClasssLoader
2.Dalvik虚拟机类加载机制

与JVM不同,Dalvik的虚拟机不能用ClassCload直接加载.dex,Android从ClassLoader派生出了两个类:DexClassLoader和PathClassLoader;而这两个类就是我们加载dex文件的关键,这两者的区别是:
1.DexClassLoader:可以加载jar/apk/dex,可以从SD卡中加载未安装的apk;
2.PathClassLoader:要传入系统中apk的存放Path,所以只能加载已经安装的apk文件。
关于Android 动态加载基础 ClassLoader工作机制大家可以参考这里:https://segmentfault.com/a/1190000004062880。
准备工作开始
- package wangyang.zun.com.mydexdemo.dynamic;
- /**
- * Created by WangYang on 2016/3/11.
- */
- public interface Dynamic {
- String sayHello();
- }
- package wangyang.zun.com.mydexdemo.dynamic.impl;
- import wangyang.zun.com.mydexdemo.dynamic.Dynamic;
- /**
- * Created by WangYang on 2016/3/11.
- */
- public class DynamicImpl implements Dynamic {
- @Override
- public String sayHello() {
- return new StringBuilder(getClass().getName()).append(" is loaded by DexClassLoader").toString();
- }
- }
很简单输出一句话,"DynamicImpl is loaded by DexClassLoader."
- //删除dynamic.jar包任务
- task clearJar(type: Delete) {
- delete 'libs/dynamic.jar'
- }
- //打包任务
- task makeJar(type:org.gradle.api.tasks.bundling.Jar) {
- //指定生成的jar名
- baseName 'dynamic'
- //从哪里打包class文件
- from('build/intermediates/classes/debug/wangyang/zun/com/mydexdemo/dynamic/')
- //打包到jar后的目录结构
- into('wangyang/zun/com/mydexdemo/dynamic/')
- //去掉不需要打包的目录和文件
- exclude('test/', 'Dynamic.class', 'BuildConfig.class', 'R.class')
- //去掉R$开头的文件
- exclude{ it.name.startsWith('R$');}
- }
- makeJar.dependsOn(clearJar, build)
打开AS的 terminal窗口: cd app进入app目录,执行gradle makeJar,然后等待直到出现Build Successfully,这时会在build目录下出现libs/dynamic.jar文件,这个文件就是我们要用的jar包,我们可以使用jd-gui打开看下是不是只有DynamicImpl这个class;
- 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;
- }
- }
- 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();
- FileUtils.copyFiles(this, "dynamic_dex.jar", desFile);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- //下面开始加载dex class
- DexClassLoader dexClassLoader = new DexClassLoader(internalPath, cacheFile.getAbsolutePath(), null, getClassLoader());
- try {
- Class libClazz = dexClassLoader.loadClass("wangyang.zun.com.mydexdemo.dynamic.impl.IDynamic");
- dynamic = (Dynamic) libClazz.newInstance();
- if (dynamic != null)
- Toast.makeText(this, dynamic.sayHelloy(), Toast.LENGTH_LONG).show();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
[转载] Android动态加载Dex机制解析的更多相关文章
- Android 插件技术:动态加载dex技术初探
1.Android动态加载dex技术初探 http://blog.csdn.net/u013478336/article/details/50734108 Android使用Dalvik虚拟机加载可执 ...
- Android 动态加载 (二) 态加载机制 案例二
探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法 重要说明 在实践的过程中大家都会发现资源引用的问题,这里重点声明两点: 1. 资源文件是不能直接inflate的,如果简单的话直接在程序 ...
- Android 动态加载 (一) 态加载机制 案例一
在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...
- Android动态加载jar/dex
前言 在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优 ...
- Android应用安全之外部动态加载DEX文件风险
1. 外部动态加载DEX文件风险描述 Android 系统提供了一种类加载器DexClassLoader,其可以在运行时动态加载并解释执行包含在JAR或APK文件内的DEX文件.外部动态加载DEX文件 ...
- Android动态加载框架汇总
几种动态加载的比较 1.Tinker 用途:热修复 GitHub地址:https://github.com/Tencent/tinker/ 使用:http://www.jianshu.com/p/f6 ...
- Android应用开发提高系列(4)——Android动态加载(上)——加载未安装APK中的类
前言 近期做换肤功能,由于换肤程度较高,受限于平台本身,实现起来较复杂,暂时搁置了该功能,但也积累了一些经验,将分两篇文章来写这部分的内容,欢迎交流! 关键字:Android动态加载 声明 欢迎转载, ...
- 【Android】Android动态加载Jar、APK的实现
本文介绍Android中动态加载Jar.APK的实现.而主要用到的就是DexClassLoader这个类.大家都知道Android和普通的Java虚拟机有差别,它只能加载经过处理的dex文件.而加载这 ...
- android动态加载
转载自: http://www.cnblogs.com/over140/archive/2012/03/29/2423116.html http://www.cnblogs.com/over140/a ...
随机推荐
- iOS开发 - OC - PCH文件使用
一. PCH文件的作用 Xcode中,PCH文件在程序编译的时候会自动包含进去.也就是说PCH中的内容是全局的,可以使用在程序的任何地方,通过这个特性,我们可以概括到PCH的作用有以下几个方面: (1 ...
- 导出DBF,并且提供下载 [转]
导出DBF,并且提供下载 #region Declare string mFilePath = MapPath("../DataTmp/"); str ...
- C#实现堆栈
堆栈(Stack)是一种特殊的线性表,是一种操作只允许在尾端进行插入或删除等操作的线性表.表尾允许进行插入删除操作,称为栈顶(Top),另一端是固定的,称为栈底(Bottom).栈的操作使按照先进后出 ...
- XE6 & IOS开发之免证书真机调试(2):连接真机并运行App(有图有真相)
网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 连接真机前,请先确保真机 ...
- [python实现设计模式]-3.简单工厂模式-触宝开放平台
预备知识: 开放封闭原则(Open-Closed Principle OCP) Software entities(classes,modules,functions etc) should open ...
- java、tomcat环境变量的配置(针对windows)
重做了下系统. 于是所有的软件都没了. 好吧,我是故意的,就是把那些我不知道的东西都删掉.. 于是问题来了,java安装好了,tomcat也粘贴完了,环境变量怎么办? 好吧,首先从可爱的java或者说 ...
- python 中变量的命名方法
从网上找到django中python的命名规范 Python 规范 代码的布局 编码 所有的Python脚本文件都应在文件头标上“# -*- coding:utf-8 -*-”. 缩进 4个空格 ...
- 浅谈数位DP
在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字, ...
- jquery用append添加按钮之后,按钮监听无法使用的解决方法
<!DOCTYPE html><html><head><meta charset="utf-8"> <title>< ...
- 【转】MaxScript.Net接收本地端口的消息执行
MaxScript里开不了线程,但是可以用.Net的BackgroundWorker来做后台处理 BackgroundWorker Fn BackgroundTcpListenerDoWork the ...