Android插件开发 老生常谈问题

1 Android类加载

PathClassLoader

DexClassLoader

两者都继承自BaseDexClassLoader

但是两者又有区别

PathClassLoader 是加载apk包的路径 比如/data/data/包名/XXXX.dex

DexClassLoader 可以加载指定apk包路径和dex文件解压路径  比如/sdcard

本文热更插件原理 基于tinker 原理实现

TINKER原理

1.使用DexClassLoader加载补丁包的dex文件

2.通过反射获取DexClassLoader类的pathList,再次通过反射获得dexElements数组。

3.获取加载应用类的PathClassLoader,同样通过反射获取它的dexElements数组。

4.合并两个dexElements数组,且将补丁包的dex文件放在前面。

代码实现

1 我们建一个需要fix 的类  MainActivity.java

package com.example.fixtest;import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;public class MainActivity extends Activity {public TextView fixText ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);fixText = findViewById(R.id.fixtext);testFix();myadd(2,3);}public void testFix(){fixText.setText("修复之前 显示错误");Log.e("mytag","fix before");}public int myadd(int a, int b){return a+b;}}

接来下我们骚骚修改一下 把修改的java 制作打包成dex

package com.example.fixtest;import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;public class MainActivity extends Activity {public TextView fixText ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);fixText = findViewById(R.id.fixtext);testFix();myadd(2,3);}public void testFix(){fixText.setText("修复之后 显示正确");Log.e("mytag","fix before");}public int myadd(int a, int b){return a+b;}}

2 将java打包成dex

需要用到的工具 dx.bat

工具路径 \android-sdk-windows\build-tools\29.0.0

添加环境变量

使用

dx --dex --output=表示打包输出/hotfix.dex 表示原文件的路径名

将一下目录 打包为dex  也可以单独复制出来 我是单独复制出来的 删除了没有必要的类

单独复制出来

在 com 同级目录 执行一下命令既可以生成 dex

dx --dex --output=./hotfix.dex ./

由于我没有服务器 我直接复制到 项目的assets 下 然后拷贝到apk 的缓存目录 然后执行加载操作

public class MyAppliction extends Application {protected void attachBaseContext(Context base) {FixManeger.copyDex(base);FixManeger.loadDex(base);super.attachBaseContext(base);}
}
public class FixManeger {public static void copyDex(Context context) {File filedex = new File(context.getCacheDir() + "/hotfix.dex");if(filedex.exists()) {filedex.delete();}try {InputStream ins = context.getAssets().open("hotfix.dex");byte[] buffer = new byte[ins.available()];ins.read(buffer);ins.close();FileOutputStream outs = new FileOutputStream(filedex);outs.write(buffer);outs.close();}catch(Exception e) {e.printStackTrace();}}public static void loadDex(Context context) {File filedex = new File(context.getCacheDir() + "/hotfix.dex");if(filedex.exists()) {try { //通过反射获取dexElements 成员 ClassLoader classLoader = context.getClassLoader();Field pathListField = BaseDexClassLoader.class.getDeclaredField("pathList");pathListField.setAccessible(true);Object pathListObject = pathListField.get(classLoader);Field dexElementsField = pathListObject.getClass().getDeclaredField("dexElements");dexElementsField.setAccessible(true);Object dexElementsObject = dexElementsField.get(pathListObject);Object newDexElementsObject = dexElementsField.get(pathListField.get(new PathClassLoader(filedex.getPath(), classLoader.getParent())));int oldLength = Array.getLength(dexElementsObject);int newLength = Array.getLength(newDexElementsObject);//开始拼接dexObject concatDexElementsObject = Array.newInstance(dexElementsObject.getClass().getComponentType(), oldLength + newLength);//加载新的dexint i;for(i = 0; i < newLength; ++i) {Array.set(concatDexElementsObject, i, Array.get(newDexElementsObject, i));}//加载原有的dexint oldindex = 0;while(oldindex < oldLength) {Array.set(concatDexElementsObject, newLength + oldindex, Array.get(dexElementsObject, oldindex));++oldindex;classLoader = classLoader;}dexElementsField.set(pathListObject, concatDexElementsObject);}catch(NoSuchFieldException e) {e.printStackTrace();}catch(IllegalAccessException e) {e.printStackTrace();}return;}}
}

Android 插件开发实现相关推荐

  1. android插件框架机制的选择,Android插件开发初探——基础篇

    Android插件开发初探 对于Android的插件化其实已经讨论已久了,但是市面上还没有非常靠谱成熟的插件框架供我们使用.这里我们就尝试性的对比一下Java中,我们使用插件化该是一个怎么样的流程,且 ...

  2. android插件开发,使用360加固自动多渠道打包

    android插件开发,使用360加固自动多渠道打包 最近研究了一下安卓插件的开发,就以开发一个360加固自动打包插件为例,练了一下,本次使用android studio基于kotlin构建自动打包插 ...

  3. Android插件开发初探——分析篇

    承接上文 Android插件开发初探--基础篇 http://blog.csdn.net/yzzst/article/details/45582315 我们通过使用DexClassLoader能够将c ...

  4. 谷歌浏览器android插件开发工具,ARC Welder:在谷歌浏览器运行安卓APK

    ARC Welder插件开发背景 现在的手机操作系统是IOS和Android的天下,很多开发人员之前想要在电脑上跑 Android APP,大部份都是安装模拟器,但这些模拟器有些并不是太好用,或是安装 ...

  5. 如何导出android studio程序,Android Studio 如何导出 Jar 给 Unity 使用

    大致步骤如下:1.创建新的 Android Studio 工程2.为此 Android Studio 工程创建 Android Library 类库(也就是一个 Module)(后面就是用它生成 ja ...

  6. 插件开发遇到的坑------final 型变量,编译过程被优化

    android 插件开发遇到的坑 今天遇到一个坑,pdf 插件,调用了主工程的一个静态final 字符串,但是主工程里面已经没有这个字符串了,却没有崩溃. 后来同事说,因为字符串可能已经直接被写死了. ...

  7. c 调用 android jar包,Unity调用AndroidStudio导出的Jar包

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 课程内容制作步骤介绍 创建AndroidStudio工程及Jar包导出 Unity中调用Jar包函数 制作步骤 大致步骤 ...

  8. 未配置appkey或配置错误,uniapp原生安卓插件开发

    开发安卓原生插件 一.官方文档 1.https://nativesupport.dcloud.net.cn/NativePlugin/course/android 2.下载对应的SDK.工程文件 二. ...

  9. 初学者---Android 学习资料

    转自: 1.hanhailong/AndroidStudyResources https://github.com/hanhailong/AndroidStudyResources 2.Android ...

最新文章

  1. Magento 模版路径
  2. php mysql 配置
  3. python2和3的区别字符编码格式上下文管理is和==的区别
  4. kotlin学习笔记——Kotlin Android Extensions
  5. 为什么我不信任通配符,以及为什么我们仍然需要通配符
  6. 三角形数、五边形数和六角形数
  7. 如何在.NET控制台应用程序中获取应用程序的路径?
  8. linux mint 18安装中文,无法在Linux Mint 18.1“Serena”下安装pyFFTW
  9. 每天备份数据库中的表
  10. 线性代数 n维向量思维导图总结(看这一张就完事了)
  11. 有效沟通bic法则_职场中5个有效沟通的法则
  12. 程序员的8个职业发展方向,了解一下!
  13. 1894 完美的牛栏
  14. MySQL数据库表数据迁移--ibd的使用
  15. ABO区块链在医疗行业中的重要作用
  16. mac OS系统中 设置ssh连接端口
  17. 智能电视是否是一台计算机,误区四 智能电视代替电脑使用_平板电视_液晶电视评测-中关村在线...
  18. 线性代数需要注意的一些点
  19. java 进阶笔记线程与并发之ForkJoinPool简析
  20. 在VMware中安装CentOS7(超详细的图文教程)

热门文章

  1. gc日志一般关注什么_理解GC日志
  2. 腾讯云「轻量应用服务器」开放公测!
  3. 嵌入式单片机基础篇(一)之stm32F1GPIO详解
  4. python 请在微信客户端打开_完美解决 请在微信客户端打开链接
  5. nginx 之 http 转 https (两种方式)
  6. js获取当前日期,并且转化为时间格式“yyyy-MM-dd HH:MM:SS”
  7. 古有陈天华万字血书抗沙俄,今有本剧蒻万字背包虐dp(01,完全,多重,分组,混合等各种背包详解 + 板子题+ 奇奇怪怪滴变式题)
  8. 天猫精灵连接蓝牙摸索1 关于阿里巴巴蓝牙MESH芯片TG7100B LINUX 开发环境塔建图文说明
  9. 五位本科生4个月造出芯片毕业!新的后续来了……
  10. 梅长苏:因为人的心,会变得越来越硬