美团robust使用

最近在整理各个热修复的使用方法和原理,第一个研究的是美团的robust
github地址为robust
基本的使用方法其实github上面有,但是我发现我集成花费了一天的时间,还有是有很多坑的所以才写了这篇文章记录一下

首先是APP目录的build里面增加我红色箭头标记的

在这里插入图片描述
带箭头的就是新增的
出了增加美团的热修复包外,还增加了权限库和分包库multidex

apply plugin: 'com.android.application'
//制作补丁时将这个打开,auto-patch-plugin紧跟着com.android.application
//apply plugin: 'auto-patch-plugin'
apply plugin: 'robust'
	
	
implementation 'com.meituan.robust:robust:0.4.99'
    implementation 'com.github.tbruyelle:rxpermissions:0.12'
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
    implementation 'io.reactivex.rxjava3:rxjava:3.0.5'
    implementation 'com.android.support:multidex:1.0.3'

接下来是配置根目录的build
在这里插入图片描述

注意如果是用kotlin开发的话,这里的gradle版本和kotlin版本不能太高,否则会报错

第一个错误
java.lang.RuntimeException: java.io.IOException: invalid constant type: 19 at 5
第二个错误
Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'task ':app:packageNjfBetaRelease' property 'resourceFiles'' with class 'org.gradle.api.internal.file.DefaultFilePropertyFactory$DefaultDirectoryVar' to class 'java.io.File'

在github的issue里面有解决办法
issue439
另外一个解决办法就是降低你的gradle版本
这里是第一个容易出问题的地方

继续看APP的build里面
在这里插入图片描述
分包记得打开
在这里插入图片描述
配置好签名,到时候测试的时候最好是打release包带签名的
在这里插入图片描述
配置签名,打开混淆
混淆文件中记得添加

-keepclassmembers class **{
public static com.meituan.robust.ChangeQuickRedirect *;
}

接下来在APP的目录下面新建robust.xml文件
里面的具体配置直接copy github里面的
robust.xml
在这里插入图片描述

注意上面几个地方修改成你自己的

接下来manifest记得配置权限

  <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

接下来开始写测试布局
mainActivity

lateinit var textView: TextView

    override
    fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        textView = findViewById(R.id.content_tv)

        val file =
            File(externalCacheDir?.absolutePath + File.separator + "robust" + File.separator + "patch ")
        if (!file.exists()) {
            file.mkdirs()
        }
        RxPermissions(this)
            .request(
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
            .subscribe { granted ->
            }


    }

    fun getString(): String {
        return "111"
    }

    fun loadPatch(view: View) {
        PatchExecutor(this, PatchManipulateImp(), object : RobustCallBack {
            override fun onPatchListFetched(
                result: Boolean,
                isNet: Boolean,
                patches: MutableList<Patch>?
            ) {
            }

            override fun onPatchFetched(result: Boolean, isNet: Boolean, patch: Patch?) {
                Log.d("swt", "onPatchFetched")
            }

            override fun onPatchApplied(result: Boolean, patch: Patch?) {
                Log.d("swt", "onPatchApplied")

            }

            override fun logNotify(log: String?, where: String?) {
                Log.d("swt", "logNotify")

            }

            override fun exceptionNotify(throwable: Throwable?, where: String?) {
                Log.d("swt", "exceptionNotify")

            }

        }).start()
    }
    
    fun setTV(view: View) {
        textView.text = getString()
    }

loadPatch里面有一个PatchExecutor最后记得start
主要看下第二个参数
PatchManipulateImp

class PatchManipulateImp : PatchManipulate() {
    override fun fetchPatchList(context: Context): MutableList<Patch> {
        val patch = Patch()
        patch.name = "test"
        patch.tempPath =
            context.externalCacheDir?.absolutePath + File.separator + "robust" + File.separator + "patch"
        patch.localPath =
            context.externalCacheDir?.absolutePath + File.separator + "robust" + File.separator + "patch"
        patch.patchesInfoImplClassFullName = "com.freebrio.robustdemo.PatchesInfoImpl"
        val list = arrayListOf<Patch>()
        list.add(patch)
        return list
    }

    override fun verifyPatch(context: Context?, patch: Patch?): Boolean {
        return true
    }

    override fun ensurePatchExist(patch: Patch?): Boolean {
        return true
    }
}

这里的temppath和localpath最好都设置一下吧,我没测试localpath不设置会不会有问题了,就都写了,反正temppath要设置的

然后下面俩个方法都返回true,后面导入手机的patch文件名字要改成patch_temp.jar

划重点

patch.patchesInfoImplClassFullName = “com.freebrio.robustdemo.PatchesInfoImpl”
这个包名和robust.xml里面patchPackname的配置要一样
然后最后的PatchesInfoImpl一定要写死
这里我们的类名是PatchManipulateImp但是这个地方一定要写死PatchesInfoImpl
不然会到时候抱错

PatchsInfoImpl failed,cause of java.lang.ClassNotFoundException:

到这里基本的配置就弄完了,开始打release包

./gradlew assembleRelease

在这里插入图片描述
打到成功后如果能出现下面几个文件那就说明前面配置的没什么大问题了
在这里插入图片描述
接下来在APP的目录下面新建robust文件夹把那俩个文件放进去
在这里插入图片描述
把APK安装到手机里面,这个APK就是我们未修复的版本
接下来我们修改mainActivity
在修改的地方添加@modify注释
同事新增一个方法,点击按钮的时候,调用getstring1方法返回222


    @Modify
    fun setTV(view: View) {
        textView.text = getString1()
    }

    @Add
    fun getString1(): String {
        return "222"
    }

然后把APP的build文件中的
在这里插入图片描述
这个插件打开
就下来继续执行
./gradlew assembleRelease
打包会失败但是没关系出现了下面的这个就可以了
在这里插入图片描述
然后再build目录下面会看到这个文件
在这里插入图片描述
将这个文件push到我们的手机中

 adb push /Users/yanzhe/android/hotfixAll/robust/app/build/outputs/robust/patch.jar /storage/emulated/0/Android/data/com.freebrio.robustdemo/cache/robust/patch_temp.jar

这是我的路径你们修改成自己的路径就可以了
记得push的jar包名字为patch_temp.jar
不要问我为什么
接下来打开我们未修复的APP,点击按钮
在这里插入图片描述
我们第一下点击的时候textview是111,加载补丁之后,在点击就变成了222
同时log里面会有这个提示
在这里插入图片描述
就证明这次补丁加载成功了
我的代码地址为
github

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值