安卓热修复 Andfix&Tinker(含 Tinker 配置及使用方法)

网上有关于几个热修复框架的功能对比,对比下来Tinker的功能比较强大一些,但是接入麻烦;Andfix接入简单,但

没有Tinker功能多,但是,都不支持加固(用的是360加固测试的)网上已经有好多文章说怎么接入的,自己也记录

一下,加深印象。如果能帮助到一两个人,那是极好的大笑

一、阿里Andfix

参考文章: AndFix使用说明

文章提中提到:

1.加载过的补丁会被保存到data/packagename/files/apatch_opt目录下,所以下载过来的补丁用过一次就可以删除了,在初始化版本信息的时候每次appversion变更都会导致所有补丁被删除,如果appversion没有改变,则会加载已经保存的所有补丁;

其他参考文章:

AndFix热修复初步上手(文章中说patch文件必须放在sdcard根目录下,我没有试过放在其他路径)

比较详细的一篇:

Android 热补丁技术——资源的热修复


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

二、微信Tinker

github地址:Tencent/tinker

现在版本已经更新到1.7.7,这里以1.7.6为例。

大体上分为四步:

1.添加tinker-gradle-plugin,在project的build.gradle里添加

classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.7.6')

如图:
 

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


2.在app/build.gradle中添加依赖:

compile 'com.android.support:multidex:1.0.1'
//可选,用于生成applicationprovided('com.tencent.tinker:tinker-android-anno:1.7.6') { changing = true }
//tinker的核心库
compile('com.tencent.tinker:tinker-android-lib:1.7.6') { changing = true }

如图:


然后继续修改此文件,其实就是比较一下自己的gradle和demo里的差了哪些东西,少的东西复制上去稍作修改就行;

官方文档里说要直接添加

apply plugin: 'com.tencent.tinker.patch'


其实不用,demo里是根据一个标志位 tinkerEnabled去判断是否使用的,标志位上注释是:

for some reason, you may want to ignore tinkerBuild, such as instant run debug build

就是说可能有些情况不需要使用tinkerBuild,比如使用instant run


整理了一下需要复制的地方:

1.在android模块里加入:

//recommend
dexOptions {
    jumboMode = true
}
 
sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}

2.在android的defalutConfig{}里加入

	multiDexEnabled true        
        buildConfigField "String", "MESSAGE", "\"I am the base apk\""
        buildConfigField "String", "TINKER_ID", "\"${getTinkerIdValue()}\""
        buildConfigField "String", "PLATFORM", "\"all\""
加入后是这样



3.剩下的就是一股脑复制就行了,贴图说明,我没有把里面的代码展开,结构看着更清晰一些:




对上面这些东西稍作一些说明,看一下比较容易明白的。

(1)gitSha():

如果没使用git的话可以把里面的值写死,不然会报错说tinkerId没有设置;

这个方法会在getTinkerIdValue()里用到。

def gitSha() {
    try {
//        String gitRev = 'git rev-parse --short HEAD'.execute(null, project.rootDir).text.trim()
        String gitRev = "TINKERID" //写死
        if (gitRev == null) {
            throw new GradleException("can't get git rev, you should add git to 
		system path or just input test value, such as 'testTinkerId'")
} return gitRev } catch (Exception e) { throw new GradleException( "can't get git rev, you should add git to system p
		path or just input test value, such as 'testTinkerId'")
}}

(2)bakApk

如果使用tinkerBuild,会在项目app/build 目录下生成bakApk文件夹,里面会复制打包生成的apk、mapping文件(只在release打包会生成)以及R文件

(3)ext,加了中文注释

 
ext {
    //for some reason, you may want to ignore tinkerBuild, such as instant run debug build?
    //是否使用tinkerBuild的标志位,在下面buildWithTinker()中会用到
    tinkerEnabled = true

    //for normal build
    //old apk file to build patch apk
    //app/build文件夹下生成的apk文件名
    tinkerOldApkPath = "${bakPath}/app-debug-0116-14-53-58.apk"
    //proguard mapping file to build patch apk
    //app/build文件夹下生成的mapping文件,在getApplyMappingPath()使用
    tinkerApplyMappingPath = "${bakPath}/"
    //resource R.txt to build patch apk, must input if there is resource changed
    //app/build文件夹下生成的R文件,getApplyResourceMappingPath()中使用
    tinkerApplyResourcePath = "${bakPath}/app-debug-0116-14-53-58-R.txt"

    //only use for build all flavor, if not, just ignore this field    //多渠道我这里没用
    tinkerBuildFlavorDirectory = "${bakPath}/app-1018-17-32-47"
}

(4)getOldApkPath()、getApplyMappingPath()和getApplyResourceMappingPath()

获取生成apk,mapping和R文件的路径,默认就是路径app/build/bakApk,加ext{...}中的几个路径

(5) buildWithTinker()

是否使用tinkerBuild

(6)getTinkerBuildFlavorDirectory

多渠道相关,这里我没有用

(7)if (buildWithTinker()) {}




上图中其他部分是和多渠道有关的,这里不使用

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

3.复制demo中的java文件

如图:



复制后会有错误重新导包就可以了;

另外,在BuildInfo类中有MESSAGE、TINKER_ID、PLATFORM几个字段,用的是BuildConfig类中的属性值。

BuildConfg是编译自动生成的(路径是:

app\build\generated\source\buildConfig\debug\com\yq\tinkertest),这几个属性是在app/build.gradle的android{...}模

块中的defaultConfig{...}中设置的,之前已经复制粘贴过了。只是我刚开始不知道这几个属性的作用,复制的时候没有

复制,导致BuildInfo中报错,所以拎出来记一下。


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

4.自定义Application类

官方推荐的是使用注释生成Application,就按官方的来。

新建类SampleApplicationLike(名字就按照demo的取了)继承DefaultApplication,重写一些方法,做一些需要的初

始化操作(把demo中的拷过来就可以了)。

重要的是这个类上面的注释,如图:



这样,编译时会在会在app/build文件夹对应路径下生成MyApplication.class文件,在manifest.xml里引入MyApplication

就可以了。或者现在manifest.xml中引入,此时会报错,

rebuild项目,如果错误小时,说明成功。

使用中发现,如果MyApplication再多一个层级,即把上图图中的路径修改为:com.yq.tinkertest.app.MyApplication,

则始终会报找不到MyApplication的class文件的错误,不知道什么原因,有知道的大神还请指教。

清单文件中引入自定义Application后,加入读写存储权限,并注册一下tinker的服务

<service
    android:name=".service.SampleResultService"
    android:exported="false"/>

如果项目刚开始使用的是继承Application的自定义Application,在onCreate方法中做了一些初始化的工作,如init()方法:

public class MyApplication extends Application {
@Override
public void onCreate() {
    super.onCreate();
    init();//初始化操作
}
}


则把init()方法里的操作放在SampleApplicationLike的onCreate方法里就可以了。

如果注释的包名和你原来的MyApplication类的包名相同,则会在编译时包class文件重复的错误。

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

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

至此,tinker的引入就算完成了。

接下来就是打包了,这里以打正式包为例。将混淆打开,不然没有mapping文件

1.先打一个正式包作为初始版本,是要装到手机上的。接下来的步骤看图就可以了




在步骤3进行之前,你可以去修改bug了,就是修改代码,修改完后,执行步骤三就行了。

执行完后会在app\build\outputs\tinkerPatch路径下生成一个patch_signed_7zip.apk的差异文件,就是修复是用来加载

的补丁文件。

如果没有生成,clean一下项目重新执行步骤3。

我这里比较简单,就是两个按钮。如图:




第一个就是弹出一个toast,初始版本信息是“修改前”,修复之后信息是“修改后”,用来区分热修复时候成功。

第二个按钮就是加载补丁文件了,加载方法很简单:

TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), patchPath);

从demo中拷过来就行了。

加载完成后会有提示是否成功。修复的结果可以在刚才注册的服务SampleResultService里监听,你可以根据结果做

你自己需要的操作。加载成功的话,会将补丁文件删除。

如果加载成功要想看到效果,必须杀掉进程,重启app才可以。

还有一点就是,如果修改过资源文件,如布局的xml和value中的xml,则在上上图的步骤二中一定要将R.txt文件的路径

加上,否则不会生成补丁文件。

最后一点,网上都说,补丁文件不一定要是apk文件,可以使其他扩展名的文件,因为apk文件容易被运营商劫持。

以上只是tinker的初步接入,里面还有很多细节没有理解透彻,如果有理解错的地方,还请指正!

代码地址:https://github.com/YINQIEIE/TinkerTest

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值