Android 热更新——非侵入AOP框架

Android热更新,高级Android开发技术 那我们该怎么做才能做到年薪60万+呢,对于程序员来说,只有不断学习,不断提升自己的实力。我之前有篇文章提到过,感兴趣的可以看看,到底要学习哪些知识才能达到年薪60万+。通过职友集数据可以查看,以北京 Android 相关岗位为例,其中 【20k-30k】 薪酬的 Android 工程师,占到了整体从业者的 30.8%!北京 Android 工程师「工资收入水平 」今天重点内容是怎么去学,怎么提高自己的技术。1.合理安排时间2.找对好的系统的学习资料3.有老师带,可以随时解决问题。 阅读详情

Android 客户端应用上线以后,一旦出现Bug,一般的解决思路是发修复包升级应用,这种方式不仅耗时,更重要的是用户需要频繁的升级版本,体验不好,所以优化的思路是在不发版本的情况下热更新,以期提高用户体验。

近期GitHub新出一种非侵入运行期AOP框架Dexposed, 下面简单了解一下这个框架,GitHub地址。

简要说明:

该框架基于AOP思想,支持经典的AOP使用场景,可应用于日志记录,性能统计,安全控制,事务处理,异常处理等方面。
针对Android平台,Dexposed支持函数级别的在线热更新,例如对已经发布在应用市场上的宿主APK,当我们从crash统计平台上发现某个函数调用有bug,导致经常性crash,这时,可以在本地开发一个补丁APK,并发布到服务器中,宿主APK下载这个补丁APK并集成后,就可以很容易修复这个crash。
Dexposed是基于久负盛名的开源Xposed框架实现的一个Android平台上功能强大的无侵入式运行时AOP框架。Dexposed的AOP实现是完全非侵入式的,没有使用任何注解处理器,编织器或者字节码重写器。

Patch原理

首先从GitHub上拉下来代码有几个坑需要注意:

  • 如果想直接拿过来用,你可能会失望而归,因为patchsample这个android程序就没有入口Activity,所以需要自行新建。
  • 注意Lib包如何添加,不能直接添加在libs这个工程自建的文件中,应该放在lib文件中,并手动添加java build依赖
  • 注意使用过程中不是像GitHub上那样介绍的如此精简,需要自行添加sunApkPatch代码并适当添加捕获异常操作,防止Patch包引起Crash。
  • patchsample只是个简单的patch,如果需要增加比较复杂的patch,需要有依赖关系,为了缩小patch体积,这个依赖只能是部分依赖,所以推荐方式是将需要补丁的class文件打jar包引入依赖即可。

接下来我们看看具体的流程:

首先需要我们动态监测AOP环境

runPatchApk();

这里需要注意的是PatchMain.load()这个方法,该方法的主要用途是加载patch APK的所有类,并将实现IPatch的类添加到List中去,然后通过匹配加载的类或者类方法来实现非侵入式AOP。

public void runPatchApk() {
    if (android.os.Build.VERSION.SDK_INT == 21) {
        return;
    }
    if (!DexposedBridge.canDexposed(this)) {
        Log.d("Hotpatch", "This device doesn't support dexposed!");
        return;
    }
    File cacheDir = getExternalCacheDir();
    if (cacheDir != null) {
        String fullpath = cacheDir.getAbsolutePath() + File.separator + "PATCH_NAME.apk";
        PatchResult result = PatchMain.load(this, fullpath, null);
        if (result.isSuccess()) {
            Log.e("Hotpatch", "patch success!");
        } else {
            Log.e("Hotpatch", "patch error is " + result.getErrorInfo());
        }
    }
}

Patch实践

public class Activity extends BaseSherlockSubActivity implements
    OnNewIconUIRefreshListener {

    private void showDialog() {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Dexposed sample")
            .setMessage("Please clone patchsample project to generate apk, and copy it to \"/Android/data/PACKAGE_NAME/cache/PATCH_NAME.apk\"")
            .setPositiveButton("ok", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int whichButton) {
                }
            }).create().show();
    }
}

假如我们上线的代码中如上所示,在弹层中出现文案bug,那么该如何热更新。
代码修复操作在Patch工程中,添加如下代码:

public class DialogPatch implements IPatch {

    @Override
    public void handlePatch(final PatchParam arg0) throws Throwable {
        Class<?> cls = null;
        try {
            cls = arg0.context.getClassLoader().loadClass("com.android.activity.Activity");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return;
        }
        DexposedBridge.findAndHookMethod(cls, "showDialog", new XC_MethodReplacement() {

            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                final Activity mainActivity = (Activity) param.thisObject;
                AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);
                builder.setTitle("Fanli Dexposed sample").setMessage("The dialog is shown from patch apk!").setPositiveButton("ok", new OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {

                        Class<?> clsInner;

                        try {
                            clsInner = arg0.context.getClassLoader().loadClass("com.android.activity.OutObject");
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                            return;
                        }

                        try {
                            OutObject outObject = (OutObject) clsInner.newInstance();

                            if (outObject.callFromOutMethod()) {
                                AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);
                                builder.setTitle("Fanli Dexposed sample").setMessage("com.android.activity.OutObject is Worked!")
                                        .setPositiveButton("ok", new OnClickListener() {

                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                dialog.dismiss();
                                            }

                                        }).create().show();
                            }
                        } catch (InstantiationException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }

                    }
                }).create().show();
                return null;
            }
        });
    }

}

然后将这个patch APK 传到Server,在主APK中通过下载patch apk到指定目录,然后动态监测AOP环境并loadPatch即可实现热更新。
接下来如果应用到实际项目中需要完善的有以下几点:

  1. 动态监测AOP环境 (android server主动监测 patch包)
  2. 动态加载Patch文件 (更新pathc以后第一时间加载patch)

Patch测试结果:

基于以上实现方案测试的环境包括:
Dalvik 4.0-4.4均已经通过
目前 ART 5.0 以及以上版本 尚未通过。(待更新Native包和Jar包)

面试:各种热修复框架对比 为每个类插入一个ChangeQuickRedirect类型的静态变量,当这个字段为空时,执行旧的方法,不为空时,就可以对badMethod做拦截,执行新的逻辑,替代掉badMethod,从而达到修复的目的。超级补丁技术基于DEX分包方案,使用了多DEX加载的原理,大致的过程就是:把BUG方法修复以后,放到一个单独的DEX里,插入到dexElements数组的最前面,让虚拟机去加载修复完后的方法。与类加载方案不同的是,底层替换方案不会再次加载新类,而是直接在Native层修改原有的类,使其功能立即生效。 阅读详情

相关推荐

Android热更新技术的研究与实现(一)

1——必备引言——本文因为篇幅较长,可能会有错别字出现,望见谅。第一部分重点是将当下热门的热更新方案实现之后再研究,第二部分则是自己动手实现一个自己的热更新框架。Android热更新技术的研究与实现之研究篇———概念讲解——–热更新 相关概念这个词出现的时间已经很久了,感觉现在要找工作才来看是晚了不少,但是好东西什么时候学习都不晚的。 今天看到一句话,和大家分享下,人一生有三样东西是别人抢不走

Tomcat的Tom 3万+

android中的热更新

主要通过在classload中,创建一个dexelements的dex文件数组,根据线上的crash定位,找到对应的类文件。然后把这个类文件打包成一个dex文件后,放到这个dex文件数组的最前方。这样就会使dexclassloader在加载dex文件的时候就不会加载那个有问题的dex文件。而只会加载我们修复完了的dex文件。可以hook我们自定义的函数也可以hook安卓的函数。通过遍历dex,相同的dex时候,就会选择最前面的。阿里巴巴的无侵入热更新框架。主流的热更新框架介绍。基于DEX分包的问题。

Crazy Android 4162

Android免Root无侵入AOP框架Dexposed

Dexposed框架是阿里巴巴无线事业部近期开源的一款在Android平台下的免Root无侵入运行期AOP框架,该框架基于AOP思想,支持经典的AOP使用场景,可应用于日志记录,性能统计,安全控制,事务处理,异常处理等方面。 针对Android平台,Dexposed只支持函数级别的在线热更新,如对已经发布在应用市场上的宿主APK,当我们从crash统计平台上发现某个函数调用有bug,导致经常性cra

【博客地址迁移到】:https://zhengxiaoyong.com 5069

热修复/热更新

当APP发布上线之后,如果出现了严重的bug,通常需要重新发版来修复,但是重新走发布流程可能时间比较长,重新安装APP用户体验也不友好,所以出现了热修复,热修复就是通过发布一个插件,使APP运行的时候加载插件里面的代码,从而解决缺陷,并且对用户来说是无感的(有时候可能需要重启一下APP)。支持加载外部的 APK、Jar 或者 dex 文件,正好符合文件化的需求,所有的插件化方案都是使用 DexClassloader 来加载插件 APK 中的 .class文件的。系统类加载器,当系统启动的时候加载常用类。

qq_34178710的博客 2538

详解Android中实现热更新的原理

这篇文章就来介绍一下Android中实现热更新的原理。 一、ClassLoader 我们知道Java在运行时加载对应的类是通过ClassLoader来实现的,ClassLoader本身是一个抽象来,Android中使用PathClassLoader类作为Android的默认的类加载器,PathClassLoader其实实现的就是简单的从文件系统中加载类文件。PathClassLoade本身继承自BaseDexClassLoader,BaseDexClassLoader重写了findClass方法,该方法是ClassLoader的核心。 @Override protected Class> f

Zynq UltraScale+ MPSoC-AMP(linux+裸机)

接着 Zynq UltraScale+ MPSoC-双核裸机AMP继续 平台工具:zcu106,vitis2020.2,petalinux2019.2 文章目录1.cpu1跑裸机2.cpu0跑linux2.1petalinux设置2.2 app3.生成BOOT.bin4.zcu106测试 1.cpu1跑裸机 参照Zynq UltraScale+ MPSoC-双核裸机AMP建立的工程进行修改。BSP中stdin与out修改为uart1,uart1给裸机用,uart0给linux用。 ddr空间裸机与linu

zhuxl24的博客 5195

Dexposed热更新-偷偷改掉你的bug

新技术真是层次不穷,八月份阿里做了件深的猿心的一件小事:dexposed 开源了。来看看 dexposed 是个啥? What is it? 相信 Android 开发猿猿们都有过这个烦恼: Android 客户端应用上线以后,难免会出现一些 bug ,特别是有些 bug 可能就只需要修改部分一两句代码的事,但是有不得不修复,然后发包。频繁发包,对用户,对开发来说的都是很蛋疼的体验。所以优

1573

自动驾驶仿真:基于Carsim开发的加速度请求模型

1、自动驾驶行业中,算法端对于纵向控制的功能预留接口基本都是加速度,我们需要给控制器仿真加速度的信号,控制器才会实现对纵向功能的控制。2、Carsim或者其他动力学软件,主要提供者节气门开度和主缸压力进行控制。我们在进行联合仿真时,往往都要通过PID的方式将请求加速度转换成对应的节气门开度与主缸压力传给动力学软件进行闭环控制。

zataji的博客 6914

Android平台免Root无侵入AOP框架Dexposed使用详解

Android平台免Root无侵入AOP框架Dexposed使用详解 字数3018 阅读2893 评论13 喜欢20 @author ASCE1885的 Github 简书 微博 优快云 阿里巴巴无线事业部最近开源的Android平台下的无侵入运行期AOP框架Dexposed,该框架基于AOP思想,支持经典的AOP使用场景,可应用于日志记录,性能统计,安全控制,事务处理

艾文-- 技术总结学习专栏 910

QCustomPlot实战:从入门到精通的数据可视化

本文详细介绍了如何使用QCustomPlot进行数据可视化,从基础环境搭建到高级图表定制,涵盖实时监控、多坐标系联动等实战技巧。基于Qt的QCustomPlot库以其强大的绘图能力和灵活的API,帮助开发者快速实现专业级数据可视化效果。

weixin_29003437的博客 115

LPDDR6与LPDDR5 State Diagram技术探讨

LPDDR6与LPDDR5 State Diagram技术探讨

zilan23的博客 1176

Android热更新全认识

热更新 应用场景 刚发布的应用出现了比较严重的bug 有一些小的功能想即时的推送给用户去使用 热更新流程 1、线上检测到严重的crash 2、拉出bugfix分支并在分支上修复问题 3、jenkins构建和补丁生成 4、app通过推送或者主动拉取补丁文件 5、将bugfix代码合到master分支上 热更新原理 BaseDexClassLoader PathClassLoader Dex...

mLuoya的博客 6369

在Windows10上安装WSL2

WSL2是微软提供的Windows子系统,允许在Windows 10和11上运行Linux环境,提供更好的性能和兼容性。安装WSL2需要启用WSL功能、更新系统、安装WSL2内核,并设置为默认版本。之后,可以通过Microsoft Store安装Linux发行版,并使用WSL命令启动和管理它们。

howard2005的专栏 5941

Android新技术学习——阿里巴巴免Root无侵入AOP框架Dexposed

阿里巴巴无线事业部最近开源的Android平台下的无侵入运行期AOP框架Dexposed,该框架基于AOP思想,支持经典的AOP使用场景,可应用于日志记录,性能统计,安全控制,事务处理,异常处理等方面。 针对Android平台,Dexposed支持函数级别的在线热更新,例如对已经发布在应用市场上的宿主APK,当我们从crash统计平台上发现某个函数调用有bug,导致经常性crash,这时,可以

区长的专栏 3145

从你的全世界路过---陌陌X-SIGN还原

我们上期介绍了hook 接口方式,今天我分析so 层。学习是为了复杂的事情简单化。不用如此繁琐。跟进native_sdbyecbu37x这个函数,我们f5看伪代码 v13 = sign(v9, v10, v11, a6); 跟进这个函数 代码如下(示例): 2.代码贴入 SHA消息摘要java代码如下: java 代码如下(示例): 总结 算法,结合动态调试!

任雪飘的博客 2299

白话FOC控制中各环节的参数的意义与如何设置参数

FOC参数整定是控制系统的关键环节,如同驯马需要调节"智能马鞍"。核心参数分为三类:电流环参数(P/I/D)决定响应速度和稳定性,速度环参数需慢于电流环5-10倍带宽,系统参数(极对数、电阻等)是电机固有属性必须准确设置。调参心法:由内而外先调电流环,遵循先P后I慎用D原则,内环带宽必须大于外环。利用自动辨识工具,通过听觉(滋滋声表示P过大)和波形观察来微调,最终实现精准控制。

汽车软件开发 356

android热更新框架nuwa,Android热更新技术——Tinker、nuwa、AndFix、Dexposed

一、热修复技术作用线上app BUG紧急修复,不重新发版,不重新安装,在线远程修复问题二、局限性与适用场景补丁只能针对单一客户端版本,随着版本差异变大补丁体积也会增大;补丁不能支持所有的修改,例如AndroidManifest;补丁无论对代码还是资源的更新成功率都无法达到100%。既然补丁技术无法完全代替升级,那它适合使用在哪些场景呢?1.轻量而快速的升级2.远端调试3.数据统计4.其他(Inst...

weixin_33304686的博客 1360

搭建自己的MQTT服务器,实现设备上云(Ubuntu+EMQX)

这篇文章教大家在ECS云服务器上部署EMQX,搭建自己私有的MQTT服务器,配置EMQX实现设备上云,设备数据转发,存储;服务器我采用的华为云的ECS服务器,系统选择Ubuntu系统。

2万+

Android中热更新面试问题讲解

热更新面试问题讲解

水月洞天 1243

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

上一篇: Java设计模式 -- Singleton模式
下一篇: Java设计模式 -- 适配器模式
linroidh
博客等级 码龄16年 15粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值