配置腾讯tinker热修复

本文详述了TinkerPatch热更新技术的集成步骤,包括项目配置、权限添加、补丁生成与应用流程,适用于快速迭代场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先在tinker平台新建app,获取对应的appkey

首先在项目下的gradle文件下添加

classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.2.6"

如下图

以下几个在app的gradle文件添加:

1、添加依赖

annotationProcessor("com.tinkerpatch.tinker:tinker-android-anno:1.9.6") { changing = true }
compileOnly('com.tinkerpatch.tinker:tinker-android-anno:1.9.6') { changing = true }
implementation('com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.6') { changing = true }
implementation 'com.android.support:multidex:1.0.1'

2、添加引用

apply from: 'tinkerpatch.gradle'

3、添加签名

添加完签名不要忘了在buildTypes->release里面添加

signingConfig signingConfigs.config

4、添加ndk和multiDexEnabled

    ndk {
            //设置支持的SO库架构
            abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
        }

这样app目录下的gradle文件就配置完了,接下来添加tinkerpatch.gradle文件,可以直接复制下面的代码,文件在app目录下,更我们上面配置的gradle文件同级。

文件代码

apply plugin: 'tinkerpatch-support'

/**
 * TODO: 请按自己的需求修改为适应自己工程的参数
 */
def bakPath = file("${buildDir}/bakApk/")
def baseInfo = "app-1.0.6-0703-09-26-35"
def variantName = "release"

/**
 * 对于插件各参数的详细解析请参考
 * http://tinkerpatch.com/Docs/SDK
 */
tinkerpatchSupport {
    /** 可以在debug的时候关闭 tinkerPatch **/
    /** 当disable tinker的时候需要添加multiDexKeepProguard和proguardFiles,
     这些配置文件本身由tinkerPatch的插件自动添加,当你disable后需要手动添加
     你可以copy本示例中的proguardRules.pro和tinkerMultidexKeep.pro,
     需要你手动修改'tinker.sample.android.app'本示例的包名为你自己的包名, com.xxx前缀的包名不用修改
     **/
    tinkerEnable = true
    reflectApplication = true
    /**
     * 是否开启加固模式,只能在APK将要进行加固时使用,否则会patch失败。
     * 如果只在某个渠道使用了加固,可使用多flavors配置
     **/
    protectedApp = false
    /**
     * 实验功能
     * 补丁是否支持新增 Activity (新增Activity的exported属性必须为false)
     **/
    supportComponent = true

    autoBackupApkPath = "${bakPath}"

    appKey = "68c4e7c2d49890b1"

    /** 注意: 若发布新的全量包, appVersion一定要更新 **/
    appVersion = "1.0.6"

    def pathPrefix = "${bakPath}/${baseInfo}/${variantName}/"
    def name = "${project.name}-${variantName}"

    baseApkFile = "${pathPrefix}/${name}.apk"
    baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
    baseResourceRFile = "${pathPrefix}/${name}-R.txt"

    /**
     *  若有编译多flavors需求, 可以参照: https://github.com/TinkerPatch/tinkerpatch-flavors-sample
     *  注意: 除非你不同的flavor代码是不一样的,不然建议采用zip comment或者文件方式生成渠道信息(相关工具:walle 或者 packer-ng)
     **/
}

/**
 * 用于用户在代码中判断tinkerPatch是否被使能
 */
android {
    defaultConfig {
        buildConfigField "boolean", "TINKER_ENABLE", "${tinkerpatchSupport.tinkerEnable}"
    }
}

/**
 1. 一般来说,我们无需对下面的参数做任何的修改
 2. 对于各参数的详细介绍请参考:
 3. https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
 */
tinkerPatch {
    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
    }
}

里面主要注意3个参数baseInfo  appkey  appVersion:

baseInfo  在后面会用到,到时再说

appkey换成自己在平台申请的

其中 appVersion 要和 app下的build.gradle文件里面的versionName保持一致

接下来添加权限

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

鉴于现在的手机系统版本,不要忘了动态添加权限

android7.0即以上需要添加provide

       <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.fileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>

如果你使用的第三方库也配置了同样的FileProvider, 可以通过继承FileProvider类来解决合并冲突的问题,示例如下:

<provider
    android:name=".utils.BuglyFileProvider"
    android:authorities="${applicationId}.fileProvider"
    android:exported="false"
    android:grantUriPermissions="true"
    tools:replace="name,authorities,exported,grantUriPermissions">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"
        tools:replace="name,resource"/>
</provider>

在res目录新建xml文件夹,创建provider_paths.xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- /storage/emulated/0/Download/${applicationId}/.beta/apk-->
    <external-path name="beta_external_path" path="Download/"/>
    <!--/storage/emulated/0/Android/data/${applicationId}/files/apk/-->
    <external-path name="beta_external_files_path" path="Android/data/"/>
</paths>

然后就是新建自己的application了,别忘了在AndroidManifest.xml里面把aplication的name加上,下面整个类的代码可以复制

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        initTinkerPatch();
    }

    private void initTinkerPatch() {
        // 我们可以从这里获得Tinker加载过程的信息
        ApplicationLike tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();

        // 初始化TinkerPatch SDK
        TinkerPatch.init(
                tinkerApplicationLike
//                new TinkerPatch.Builder(tinkerApplicationLike)
//                    .requestLoader(new OkHttp3Loader())
//                    .build()
        )
                .reflectPatchLibrary()
                .setPatchRollbackOnScreenOff(true)
                .setPatchRestartOnSrceenOff(true)
                .setFetchPatchIntervalByHours(3)
        ;
        // 每隔3个小时(通过setFetchPatchIntervalByHours设置)去访问后台时候有更新,通过handler实现轮训的效果,可以改为(1-24)小时

        // fetchPatchUpdateAndPollWithInterval 与 fetchPatchUpdate(false)
        // 不同的是,会通过handler的方式去轮询
        TinkerPatch.with().fetchPatchUpdateAndPollWithInterval();
    }

    @Override
    public void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        //you must install multiDex whatever tinker is installed!
        MultiDex.install(base);
    }
}

这样所有的配置就做完了,接下就可以生成apk包了,可以先去修改mainactivity里面的布局之类的,用于后面的打补丁之后做比较,我这边是修改textview里面的内容为当前时间。生成apk的方法,点击Android studio右上角的gradle,按照下图,双击 assembleRelease

就可以在左边的工程项目下的app->build找到对应的apk,如下图

把这个apk包安装到手机,然后接下来就可以模拟打补丁了,先去修改布局里面的textview显示的时间,接着修改tinketpatch.gradle文件里面的 baseInfo,上面有提到的后面再说的那个参数。怎么修改?如图

在生成apk时,可以不管baseInfo这个参数,这时生成的可以称之为基准包,后面生成的补丁,不管是多少个补丁包,只要app的版本没有变,baseInfo的参数设置都要指向这个基准包所对应的包名。

生成补丁的方法,还是点击Android studio右上角的gradle,如下图

双击tinkerPatchRelease,就可以生成补丁包了,补丁布的路径如下图

这个patch_signed_7zip.apk就是补丁包了,接下来只要把他上传到tinker平台就算是打补丁成功了

如果你是刚生成apk包,然后马上模拟打补丁是不会里面生效的,由于MyApplication里面的这个设置setFetchPatchIntervalByHours(3),里面的3指3小时,即这个补丁3小时后才会生效(由于这个原因我一直以为我的配置是错误的)。但如果你安装apk包后,过个3小时,然后再上传补丁包,这时你杀掉app再重启,刚刚打的补丁就可以立马生效了。如果这段话有错误,欢迎各位大佬指正。

测试后发现,我下发补丁后,app要杀掉重启两次后,app才能更新到下发的补丁,第一次杀掉重启只是下载和合并补丁,第二次重启才应用补丁包。不能一次重启就马上修复bug,感觉并不实用,大佬勿喷啊

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值