接入热修复框架TinKer

Tinker,是微信开源的Android热修复框架,也时在不久前才开源的,之前开源的框架也有很多,比如QZone,AndFix,Dexposed,不过Dexposed不支持全平台,AndFix无法实现类替换,QZone主要是插桩带来的Dalvik的性能问题,而Tinker不仅支持类替换,还支持全平台2.x-7.x,补丁的大小也远远小于其他方案,这都是TInker的优点。Github上Tinker的Demo写的有点复杂,一开始没看懂怎么用的,弄了前前后侯加起来快一天的时间。下面给他打介绍下Tinker的简单用法。

市热修复框架对比:



使用步骤:

1.在project的build.gradle中添加:classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.7.1')

在app的gradle中添加:

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

2.在app的dependencies外面添加配置信息:

//添加配置
apply plugin: 'com.tencent.tinker.patch'
//全局信息相关的配置项
tinkerPatch {
    //有问题的apk的地址  准apk包的路径,必须输入,否则会报错
    oldApk = "C://Users/Admin/Desktop/HotFix/apkSource/app_old.apk"
    //
    ignoreWarning = false
    //在运行过程中,需要验证基准apk包与补丁包的签名是否一致,我们是否需要为你签名
    useSign = true
    //编译相关的配置项
    buildConfig {
        //在运行过程中,我们需要验证基准apk包的tinkerId是否等于补丁包的tinkerId。
        // 这个是决定补丁包能运行在哪些基准包上面,一般来说我们可以使用git版本号、versionName等等。
        tinkerId = "1.0"
    }
    //用于生成补丁包中的'package_meta.txt'文件
    packageConfig {
        //onfigField("key", "value"), 默认我们自动从基准安装包与新安装包的Manifest中读取tinkerId,并自动写入configField。
        // 在这里,你可以定义其他的信息,在运行时可以通过TinkerLoadResult.getPackageConfigByName得到相应的数值。
        // 但是建议直接通过修改代码来实现,例如BuildConfig。
        configField("TINKER_ID", "1.0")
    }
    //dex相关的配置项
    dex {
        //只能是'raw'或者'jar'。 
        //对于'raw'模式,我们将会保持输入dex的格式。
        //对于'jar'模式,我们将会把输入dex重新压缩封装到jar。
        // 如果你的minSdkVersion小于14,你必须选择‘jar’模式,而且它更省存储空间,但是验证md5时比'raw'模式耗时()
        dexMode = "jar"
        //需要处理dex路径,支持*、?通配符,必须使用'/'分割。路径是相对安装包的,例如/assets/...
        pattern = ["classes*.dex", "assets/secondary-dex-?.jar"]
        //它定义了哪些类在加载补丁包的时候会用到。这些类是通过Tinker无法修改的类,也是一定要放在main dex的类。
        loader = ["com.tencent.tinker.loader.*", "com.tinkertest.Application"]
        /**
         * 这里需要定义的类有:
         1. 你自己定义的Application类;
         2. Tinker库中用于加载补丁包的部分类,即com.tencent.tinker.loader.*; 
         3. 如果你自定义了TinkerLoader,需要将它以及它引用的所有类也加入loader中;
         4. 其他一些你不希望被更改的类,例如Sample中的BaseBuildInfo类。这里需要注意的是,
         这些类的直接引用类也需要加入到loader中。或者你需要将这个类变成非preverify。
         */
    }
    //lib相关的配置项
    lib {
        //需要处理lib路径,支持*、?通配符,必须使用'/'分割。与dex.pattern一致, 路径是相对安装包的,例如/assets/...
        pattern = ["lib/armeabi/*.so", "lib/arm64-v8a/*.so", "lib/armeabi-v7a/*.so", "lib/mips/*.so", "lib/mips64/*.so", "lib/x86/*.so", "lib/x86_64/*.so"]
    }
    //res相关的配置项
    res {
        pattern = ["res/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]
        //对于修改的资源,如果大于largeModSize,我们将使用bsdiff算法。
        // 这可以降低补丁包的大小,但是会增加合成时的复杂度。默认大小为100kb
        largeModSize = 100
    }
    //7zip路径配置项,执行前提是useSign为true
    sevenZip {
        //例如"com.tencent.mm:SevenZip:1.1.10",将自动根据机器属性获得对应的7za运行文件,推荐使用。
        zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
    }
}

3.建立自己的application:

@DefaultLifeCycle(
        application = "cn.tinker.com.mytinker.Application",
        flags = ShareConstants.TINKER_ENABLE_ALL
)

//

其中application属性中的内容是包名加上类名,类名由自己随便定义,只要到时候与manifest中的声明一致就行,
* Application是有TInker来自动生成的,application="com.xxxx.Application"就是被自动生成的Application;
public class MyApp extends DefaultApplicationLike {


    public MyApp(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);
    }


    /**
     * 重写DefaultApplicationLike方法
     * @param base
     */
    @Override
    public void onBaseContextAttached(Context base) {
        super.onBaseContextAttached(base);
        TinkerInstaller.install(this);
    }
}

4.配置manifest:


配置完manifest 会报错  构建下项目就好了;

5.

public class MainActivity extends AppCompatActivity {
    private Button btn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn= (Button) findViewById(R.id.btn);
        TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), Environment.getExternalStorageDirectory().getAbsolutePath() + "/HotFix/patch_signed_7zip.apk");
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "错误的《《《", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

6.

下一步就是打包项目,运行apk在手机上;点击按钮 肯定toast“错误的<<<”内容;

然后修改toast里面的内容 保存;


根据上图指示操作  双击tinkerPatchDebug;


等生成差异文件成功!


找到图中选中的文件;

Tinker输出文件详解和接入中文指南:点击打开

在MainActivity中 为了加载方便,我把文件放在了手机HotFix目录下;

对源码和原理感兴趣的可以去看看:点击查看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值