微信热修复框架Tinker的使用

1、在project目录下的build.gradle的dependencies下添加如下代码:

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

2、添加依赖配置到你的app/build.gradle的dependencies下:

provided('com.tencent.tinker:tinker-android-anno:1.7.1')
compile('com.tencent.tinker:tinker-android-lib:1.7.1')

3、在app/build.gradle的dependencies的最外层添加下面这些配置:

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

ext {
    
    tinkerEnabled = true

    //for normal build
    //原来的apk地址
    tinkerOldApkPath = "${bakPath}/app-debug-1028-12-47-25.apk"

    //如果资源文件改变了,这项必须填写
    //tinkerApplyResourcePath = "${bakPath}/app-debug-1018-17-32-47-R.txt"

    //只用于多渠道打包,没有的可以忽略
   //tinkerBuildFlavorDirectory = "${bakPath}/app-1018-17-32-47"
}


def getOldApkPath() {
    return hasProperty("OLD_APK") ? OLD_APK : ext.tinkerOldApkPath
}

/*def getApplyMappingPath() {
    return hasProperty("APPLY_MAPPING") ? APPLY_MAPPING : ext.tinkerApplyMappingPath
}*/

/*def getApplyResourceMappingPath() {
    return hasProperty("APPLY_RESOURCE") ? APPLY_RESOURCE : ext.tinkerApplyResourcePath
}*/

//TINKER_ID可以自己指定
def getTinkerIdValue() {
    return hasProperty("TINKER_ID") ? TINKER_ID : "100"
}

def buildWithTinker() {
    return hasProperty("TINKER_ENABLE") ? TINKER_ENABLE : ext.tinkerEnabled
}

/*def getTinkerBuildFlavorDirectory() {
    return ext.tinkerBuildFlavorDirectory
}*/

if (buildWithTinker()) {
    apply plugin: 'com.tencent.tinker.patch'

    tinkerPatch {
       //必须的
        oldApk = getOldApkPath()
       //可选的,默认为false
        ignoreWarning = false

       //可选,默认为true
        useSign = true

        buildConfig {

            //可选的,由于这用不到所以注释掉了
//            applyMapping = getApplyMappingPath()
            //可选
//            applyResourceMapping = getApplyResourceMappingPath()

            //必须的
            tinkerId = getTinkerIdValue()
        }

        dex {
           //可选,默为jar
            dexMode = "jar"
           //可选,默认为false
            usePreGeneratedPatchDex = false
           //必须的,默认为[]
            pattern = ["classes*.dex",
                       "assets/secondary-dex-?.jar"]
            //必须的,默认为[]
            loader = ["com.tencent.tinker.loader.*",
                      //这里必须换成你自己的Application
                      "tinker.sample.android.app.SampleApplication"]
        }

        lib {
           //可选,默认为[]
            pattern = ["lib/armeabi/*.so"]
        }

        res {
            //可选,默认为[]
            pattern = ["res/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]

            //可选,默认为[]
            ignoreChange = ["assets/sample_meta.txt"]

            //默认为100kb
            largeModSize = 100
        }

        packageConfig {
            //可选
            configField("patchMessage", "tinker is sample to use")

        }
       
        /**
         * if you don't use zipArtifact or path, we just use 7za to try
         */
        sevenZip {

            //可选,默认为7zip
            zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
            /**
             * optional,default '7za'
             * you can specify the 7za path yourself, it will overwrite the zipArtifact value
             */
//        path = "/usr/local/bin/7za"
        }
    }

    /**
     * bak apk and mapping
     */
    android.applicationVariants.all { variant ->
        /**
         * task type, you want to bak
         */
        def taskName = variant.name

        tasks.all {
            if ("assemble${taskName.capitalize()}".equalsIgnoreCase(it.name)) {
                it.doLast {
                    copy {
                        def date = new Date().format("MMdd-HH-mm-ss")
                        from "${buildDir}/outputs/apk/${project.getName()}-${taskName}.apk"
                        into bakPath
                        rename { String fileName ->
                            fileName.replace("${project.getName()}-${taskName}.apk", "${project.getName()}-${taskName}-${date}.apk")
                        }

                        from "${buildDir}/outputs/mapping/${taskName}/mapping.txt"
                        into bakPath
                        rename { String fileName ->
                            fileName.replace("mapping.txt", "${project.getName()}-${taskName}-${date}-mapping.txt")
                        }

                        from "${buildDir}/intermediates/symbols/${taskName}/R.txt"
                        into bakPath
                        rename { String fileName ->
                            fileName.replace("R.txt", "${project.getName()}-${taskName}-${date}-R.txt")
                        }
                    }
                }
            }
        }
    }

}

4、自定义applicaiton继承DefaultApplicationLike,并且添加注解@DefaultLifeCycle,如果你之前的代码已经有自定义的application,可以将你的application继承DefaultApplicationLike,而不是Applicaiton。

@DefaultLifeCycle(application = "com.ress.tinker.app.SampleApplicaiton",
                  flags = ShareConstants.TINKER_ENABLE_ALL)
public class MyApplication extends DefaultApplicationLike {

    public MyApplication(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent, Resources[] resources, ClassLoader[] classLoader, AssetManager[] assetManager) {
        super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent, resources, classLoader, assetManager);
    }

application=“com.ress.tinker.app.SampleApplication"中的类名可以自己定义,这个类将由TInker自动生成。并在AndroidManifest,xml文件的applicaiton标签中声明。

<application
        android:name=".app.SampleApplicaiton"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

5、重写MyApplicaiton的OnBaseContextAttached()方法,并初始化TInker

@DefaultLifeCycle(application = "com.ress.tinker.app.SampleApplicaiton",
                  flags = ShareConstants.TINKER_ENABLE_ALL)
public class MyApplication extends DefaultApplicationLike {

    public MyApplication(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent, Resources[] resources, ClassLoader[] classLoader, AssetManager[] assetManager) {
        super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent, resources, classLoader, assetManager);
    }

    @Override
    public void onBaseContextAttached(Context base) {
        super.onBaseContextAttached(base);
        TinkerInstaller.install(this);
    }
}


6、加载修复代码

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TinkerInstaller.onReceiveUpgradePatch(MainActivity.this, Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk");

        Toast.makeText(this, "有Bug!!", Toast.LENGTH_SHORT).show();
    }
}

Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk"
这是修复后的apk放在手机中的位置


6、打开android studio右侧的gradle面板,找到assembleDebug,双击

7、打开build/bakapk,将apk装到手机里


将apk名字复制到之前app/build.gradle中的tinkerOldApk处

ext {
    //for some reason, you may want to ignore tinkerBuild, such as instant run debug build?
    tinkerEnabled = true

    //for normal build
    //原来的apk地址
    <span style="color:#ff6666;">tinkerOldApkPath = "${bakPath}/app-debug-1028-12-47-25.apk"</span>

    //如果资源文件改变了,这项必须填写
    //tinkerApplyResourcePath = "${bakPath}/app-debug-1018-17-32-47-R.txt"

    //只用于多渠道打包,没有的可以忽略
   //tinkerBuildFlavorDirectory = "${bakPath}/app-1018-17-32-47"
}

8、修改土司的内容,再次打开android studio右侧的gradle面板,双击tinker/tinkerPatchDebug

9、在build/outputs/tinkerpatch下找到patch_signed_7zip.apk,并拷贝到手机内存根目录


注意:

不能忘记权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
10、运行之前的apk,干掉进程之后再次打开,会发现土司的内容变了。

最后感谢简书红飞大神的基于腾讯Tinker热修复框架的Demo和腾讯的Tinker,才能顺利的集成Tinker。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值