小工具知识网

当前位置: 首页 > 行业知识 > Android热更新,高级Android开发技术

行业知识

Android热更新,高级Android开发技术

2026-11-08 06:10:52 来源:互联网转载
    • 1.Android中如何动态修复bug
    • 2.Android中的类加载器

    • 3.热修复的实现原理

    • 三.热更新优点

        • 为什么要做热更新
        • 四.热更新使用

          • 1.添加插件依赖
          • 2.集成SDK

          • 3.初始化SDK

          • 4.Androidmanifest.xml配置

          • 5.混淆配置

          • 6.常见错误

            一.什么是热更新

            ==================================================================

            热更新是一种各大手游等众多App常用的更新方式。简单来说,就是在用户通下载安装APP之后,打开App时遇到的即时更新。

            二.工作原理

            ================================================================

            热更新就是动态下发代码,它可以使开发者在不发布新版本的情况下,修复 BUG 和发布功能,让开发者得以绕开苹果的审核机制,避免长时间的审核等待以及多次被拒造成的成本。

            1.Android中如何动态修复bug


            bug一般是一个或多个class出现了问题,在一个理想的状态下,我们只需将修复好的这些个class更新到用户手机上的app中就可以修复这些bug了。但说着简单,要怎么才能动态更新这些class呢?其实,不管是哪种热修复方案,肯定是如下几个步骤:

            1. 下发补丁(内含修复好的class)到用户手机,即让app从服务器上下载(网络传输)

            app通过"某种方式",使补丁中的class被app调用(本地更新)

            1. 这里的"某种方式",对本篇而言,就是使用Android的类加载器,通过类加载器加载这些修复好的class,覆盖对应有问题的class,理论上就能修复bug了。所以,下面就先来了解和分析Android中的类加载器吧。

            2.Android中的类加载器


            Android更java有很大的渊源,基于jvm的java应用是通过ClassLoader来加载应用中的class的,但我们知道Android对jvm优化过,使用的是dalvik,且class文件会被打包进一个dex文件中,底层虚拟机有所不同,那么它们的类加载器当然也是会有所区别,在Android中,要加载dex文件中的class文件就需要用到 PathClassLoader 或 DexClassLoader 这两个Android专用的类加载器。

            3.热修复的实现原理


            安卓的类加载器在加载一个类时会先从自身DexPathList对象中的Element数组中获取(Element[] dexElements)到对应的类,之后再加载。采用的是数组遍历的方式,不过注意,遍历出来的是一个个的dex文件。

            在for循环中,首先遍历出来的是dex文件,然后再是从dex文件中获取class,所以,我们只要让修复好的class打包成一个dex文件,放于Element数组的第一个元素,这样就能保证获取到的class是最新修复好的class了

            三.热更新优点

            =================================================================

            1. 正常开发流程:

            新版本上线,发现问题或用户反馈bug,紧急修复,上线版本,用户重新安装。

            存着如下问题:

            l 周期长

            l 用户下载成本高,app推广成本高昂

            l 修复不及时,用户体验差,用户遇到奔溃时失去耐心后直接卸载。

            1. 热修复流程:

            新版本上线,发现问题或用户反馈,紧急修复,上线补丁,自动修复

            存着如下优点:

            l 无需重新发版,及时修复问题

            l 用户无感知修复,无需下载新应用,代价小

            l 修复成功率高,把损失降到最低

            但热修复因为大量涉及android底层知识,又因为android本身开源,华为vivo小米几大厂商都可能修改底层相关代码,兼容性困难,所以热修复技术开发维护难度巨大,人力和时间投入不菲。目前主要有腾讯,阿里等几家互联网大厂因自身刚性需求,实现此功能。

            两者实现对比:

            各种热修复技术对比:

            为什么要做热更新

            当一个App发布之后,突然发现了一个严重bug需要进行紧急修复,这时候公司各方就会忙得焦头烂额:重新打包App、测试、向各个应用市场和渠道换包、提示用户升级、用户下载、覆盖安装。

            重点是还会有原来的版本遗留,无论你怎么提示都有人放弃治疗,不愿意升级,强制不能使用体验又足够糟糕到让人不能启齿。

            如果这是一个影响公司收入或者体验影响极其不好的Bug,那完蛋了,可能公司老板会对整个技术团队的技术能力丧失信心,其对技术人员的伤害是致命的。

            最后最致命的是:

            有时候仅仅是因为不小心写错了一行代码,就让所有的工作都付之东流。

            而热更新的出现正是解决了这些问题

            四.热更新使用

            =================================================================

            以bugly技术为例:

            bugly优点:

            1. 无需关注补锅匠是如何合成补丁的

            2. 无需自己搭建补丁管理后台

            3. 无需考虑后台下发补丁策略的任何事情

            4. 无需考虑补丁下载合成的时机,处理后台下发的策略

            5. 提供了更加方便集成补锅匠的方式

            6. 我们通过HTTPS及签名校验等机制保障补丁下发的安全性

            7. 丰富的下发维度控制,有效控制补丁影响范围

            8. 提供了应用升级一站式解决方案

            1.添加插件依赖


            工程根目录下“的build.gradle”文件中添加:

            buildscript {

            repositories {

            jcenter()

            }

            dependencies {

            // tinkersupport插件, 其中lastest.release指拉取最新版本,也可以指定明确版本号,例如1.0.4

            classpath “com.tencent.bugly:tinker-support:1.1.2”

            }

            }

            2.集成SDK


            gradle这个配置

            在app module的“build.gradle”文件中添加(示例配置):

            android {

            defaultConfig {

            ndk {

            //设置支持的SO库架构

            abiFilters ‘armeabi’ //, ‘x86’, ‘armeabi-v7a’, ‘x86_64’, ‘arm64-v8a’

            }

            }

            }

            dependencies {

            compile “com.android.support:multidex:1.0.1” // 多dex配置

            //注释掉原有bugly的仓库

            //compile ‘com.tencent.bugly:crashreport:latest.release’//其中latest.release指代最新版本号,也可以指定明确的版本号,例如1.3.4

            compile ‘com.tencent.bugly:crashreport_upgrade:1.3.5’

            // 指定tinker依赖版本(注:应用升级1.3.5版本起,不再内置tinker)

            compile ‘com.tencent.tinker:tinker-android-lib:1.9.6’

            compile ‘com.tencent.bugly:nativecrashreport:latest.release’ //其中latest.release指代最新版本号,也可以指定明确的版本号,例如2.2.0

            }

            后续更新升级SDK时,只需变更配置脚本中的版本号即可。

            在app module的“build.gradle”文件中添加:

            // 依赖插件脚本

            apply from: ‘tinker-support.gradle’

            修补匠-support.gradle内容如下所示:

            apply plugin: ‘com.tencent.bugly.tinker-support’

            def bakPath = file(“${buildDir}/bakApk/”)

            /**

            • 此处填写每次构建生成的基准包目录

              */

              def baseApkDir = “app-0208-15-10-00”

              /**

              • 对于插件各参数的详细解析请参考

                */

                tinkerSupport {

                // 开启tinker-support插件,默认值true

                enable = true

                // 指定归档目录,默认值当前module的子目录tinker

                autoBackupApkDir = “${bakPath}”

                // 是否启用覆盖tinkerPatch配置功能,默认值false

                // 开启后tinkerPatch配置不生效,即无需添加tinkerPatch

                overrideTinkerPatchConfiguration = true

                // 编译补丁包时,必需指定基线版本的apk,默认值为空

                // 如果为空,则表示不是进行补丁包的编译

                // @{link tinkerPatch.oldApk }

                baseApk = “ b a k P a t h / {bakPath}/ bakPath/{baseApkDir}/app-release.apk”

                // 对应tinker插件applyMapping

                baseApkProguardMapping = “ b a k P a t h / {bakPath}/ bakPath/{baseApkDir}/app-release-mapping.txt”

                // 对应tinker插件applyResourceMapping

                baseApkResourceMapping = “ b a k P a t h / {bakPath}/ bakPath/{baseApkDir}/app-release-R.txt”

                // 构建基准包和补丁包都要指定不同的tinkerId,并且必须保证唯一性

                tinkerId = “base-1.0.1”

                // 构建多渠道补丁时使用

                // buildAllFlavorsDir = “ b a k P a t h / {bakPath}/ bakPath/{baseApkDir}”

                // 是否启用加固模式,默认为false.(tinker-spport 1.0.7起支持)

                // isProtectedApp = true

                // 是否开启反射Application模式

                enableProxyApplication = false

                // 是否支持新增非export的Activity(注意:设置为true才能修改AndroidManifest文件)

                supportHotplugComponent = true

                }

                /**

                • 一般来说,我们无需对下面的参数做任何的修改

                • 对于各参数的详细介绍请参考:

                • https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97

                  */

                  tinkerPatch {

                  //oldApk =“ b a k P a t h / {bakPath}/ bakPath/{appName}/app-release.apk”

                  ignoreWarning = false

                  useSign = true

                  dex {

                  dexMode = “jar”

                  pattern = [“classes*.dex”]

                  loader = []

                  }

                  lib {

                  pattern = [“lib//.so”]

                  }

                  res {

                  pattern = [“res/", "r/”, “assets/*”, “resources.arsc”, “AndroidManifest.xml”]

                  ignoreChange = []

                  largeModSize = 100

                  }

                  packageConfig {

                  }

                  sevenZip {

                  zipArtifact = “com.tencent.mm:SevenZip:1.1.10”

                  // path = “/usr/local/bin/7za”

                  }

                  buildConfig {

                  keepDexApply = false

                  //tinkerId = “1.0.1-base”

                  //applyMapping = “ b a k P a t h / {bakPath}/ bakPath/{appName}/app-release-mapping.txt” // 可选,设置mapping文件,建议保持旧apk的proguard混淆方式

                  //applyResourceMapping = “ b a k P a t h / {bakPath}/ bakPath/{appName}/app-release-R.txt” // 可选,设置R.txt文件,通过旧apk文件保持ResId的分配

                  }

                  }

                  3.初始化SDK


                  enableProxyApplication = false的情况

                  集成Bugly升级SDK之后,我们需要按照以下方式自定义ApplicationLike来实现的应用的代码(以下是示例):

                  自定义应用程序

                  public class SampleApplication extends TinkerApplication {

                  public SampleApplication() {

                  super(ShareConstants.TINKER_ENABLE_ALL, “xxx.xxx.SampleApplicationLike”,

                  “com.tencent.tinker.loader.TinkerLoader”, false);

                  }

                  }

                  参数1:tinkerFlags表示Tinker支持的类型dex only,仅库或所有suuport,默认:TINKER_ENABLE_ALL

                  参数2:delegateClassName Application代理类这里填写你自定义的ApplicationLike

                  参数3:loaderClassName Tinker的加载器,使用默认即可

                  参数4:tinkerLoadVerifyFlag加载dex或者lib是否验证md5,默认为false

                  需要一个应用配置为继承TinkerApplication的类:

                  自定义ApplicationLike:

                  public class SampleApplicationLike extends DefaultApplicationLike {

                  public static final String TAG = “Tinker.SampleApplicationLike”;

                  public SampleApplicationLike(Application application, int tinkerFlags,

                  boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime,

                  long applicationStartMillisTime, Intent tinkerResultIntent) {

                  super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);

                  }

                  自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

                  深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

                  因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

                  既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

                  由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

                  如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

                  最后

                  那我们该怎么做才能做到年薪60万+呢,对于程序员来说,只有不断学习,不断提升自己的实力。我之前有篇文章提到过,感兴趣的可以看看,到底要学习哪些知识才能达到年薪60万+。

                  通过职友集数据可以查看,以北京 Android 相关岗位为例,其中 【20k-30k】 薪酬的 Android 工程师,占到了整体从业者的 30.8%!

                  北京 Android 工程师「工资收入水平 」

                  今天重点内容是怎么去学,怎么提高自己的技术。

                  1.合理安排时间

                  2.找对好的系统的学习资料

                  3.有老师带,可以随时解决问题

                  4.有明确的学习路线

                  当然图中有什么需要补充的或者是需要改善的,可以在评论区写下来,一起交流学习。

                  《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

                  ,可以扫码获取!!(备注:Android)**

                  最后

                  那我们该怎么做才能做到年薪60万+呢,对于程序员来说,只有不断学习,不断提升自己的实力。我之前有篇文章提到过,感兴趣的可以看看,到底要学习哪些知识才能达到年薪60万+。

                  通过职友集数据可以查看,以北京 Android 相关岗位为例,其中 【20k-30k】 薪酬的 Android 工程师,占到了整体从业者的 30.8%!

                  北京 Android 工程师「工资收入水平 」

                  [外链图片转存中…(img-Xp8Tgjd2-1712433818050)]

                  今天重点内容是怎么去学,怎么提高自己的技术。

                  1.合理安排时间

                  2.找对好的系统的学习资料

                  3.有老师带,可以随时解决问题

                  4.有明确的学习路线

                  当然图中有什么需要补充的或者是需要改善的,可以在评论区写下来,一起交流学习。

                  [外链图片转存中…(img-Y4jfUaRM-1712433818050)]

                  《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

上一篇:Flutter性能优化

下一篇:揭秘E4A直播接口获取秘籍!