Android 7.1 Toast修复之多渠道包动态使用Booster或者Lancet plugin

兼容性问题

因在游戏公司项目中,存在大量的多渠道,情况会变得复杂化。

在使用Lancet 修复Toast 问题过程中,发现在抖音直播渠道包中,使用Lance字节编码失败,报错如下所示:
在这里插入图片描述
从上面报错可知,Lance 插件无法解析Scope.ALL_SELF导致编译失败。

定位分析

查看ReceiverRegisterLancet所在的代码,基于字节的com.bytedance.ttgame:gbsdk_common_host远程库下,详情如下:
在这里插入图片描述
在于饿了么的Lancet 库,进行比对,发现: 字节的库使用的基于Lancet二次开发的库,与原有的Lancet对不上,详情如下所示
在这里插入图片描述

解决方案

使用另外的字节编码方案来修复7.1 系统Toast Bug, 比如滴滴出行开源的Booster,更多详情阅读Booster使用文档

在Booster 中,也是通过Hook Toast 方式(即 hook TN#Handler), 来进行对class 的全局替换,最后生成Apk。

因Lancet 的功能非常强大,可以实现许多功能,因此,只在冲突的渠道包上改用Booster 来处理Toast问题,其他渠道上正常使用Lancet 修复Toast问题。

根据渠道包动态使用Lancet 插件或者Booster插件,为了尽可能避免字节编码导致apk调试不上的问题,只在Release正式包中使用字节编码。

在项目根目录下的build.gradle:

buildscript {
    ext.ams_open=false //  是否开启字节编码
    ext.use_booster=false// 是否使用booster
    gradle.startParameter.taskNames.any {
        //通过判断任务名字,区分当前是打包哪个渠道包。对抖音直播 上Lancet 会冲突,改用booster
        // 若是后续还有渠道与lancet冲突,在这里添加变种名字
        use_booster=it.contains('douyinzhibo')|| it.contains('Douyinzhibo')
        //debug 包下不启用,防止调试断点不上
        ams_open=it.contains("release")||it.contains("Release")
        println "gradle.ext.ams_open->$ams_open "+" use_booster->$use_booster"
    }
    repositories {
      //......
    }
    dependencies {
        //......
        if (ams_open){
            if (use_booster){
                ext.booster_version = '4.15.0'
                classpath "com.didiglobal.booster:booster-gradle-plugin:$booster_version"
                classpath "com.didiglobal.booster:booster-transform-toast:$booster_version"
            }else{
                //lancet 字节编码
                classpath 'com.bytedance.tools.lancet:lancet-plugin-asm6:1.0.2'
            }
        }
    }
}

在app Module中的build.gradle:动态加载对应的plugin插件

apply plugin: 'com.android.application'
if (ams_open){
   //动态加载plugin插件
    if (use_booster) {
        apply plugin: 'com.didiglobal.booster'
    }else{
        apply plugin: 'me.ele.lancet'
    }
}

关于Lancet 修复Toast 问题,请阅读上篇Android Lancet Aop 字节编码修复7.1系统Toast问题(WindowManager$BadTokenException)

验证

当编译渠道包时,可看到字节编码开关是否开启,和是否使用Booster 。
在这里插入图片描述
当最终生成apk 后,可查看,是否已经全局替换成功:

!](https://img-blog.csdnimg.cn/0ae8954b3b6d4b9cafe6717da9cc829a.png)

从apk看的结果,可知已经替换换成Booster 中hook Toast 方案,详情如下:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过以下步骤实现自定义Toast的显示时间: 1. 自定义一个Toast的布局文件,例如:toast_layout.xml。 2. 在代码中加载该布局文件,并设置Toast的显示时间。 ``` java LayoutInflater inflater = getLayoutInflater(); View layout = inflater.inflate(R.layout.toast_layout, null); Toast toast = new Toast(getApplicationContext()); toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); toast.setDuration(Toast.LENGTH_LONG); toast.setView(layout); // 设置显示时间 final int DELAY_TIME = 2000; new Handler().postDelayed(new Runnable() { @Override public void run() { toast.cancel(); } }, DELAY_TIME); toast.show(); ``` 在上面的代码中,通过Toast的setView方法设置了自定义的布局文件,然后通过Handler定时取消Toast的显示。 注意:这里设置的显示时间需要根据实际情况进行调整,DELAY_TIME为毫秒数。 3. 如果需要多次显示Toast,可以将以上代码封装成一个方法,然后在需要显示Toast的地方调用该方法即可。 ``` java public static void showCustomToast(Context context, String msg) { LayoutInflater inflater = LayoutInflater.from(context); View layout = inflater.inflate(R.layout.toast_layout, null); TextView text = (TextView) layout.findViewById(R.id.text); text.setText(msg); Toast toast = new Toast(context); toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); toast.setDuration(Toast.LENGTH_LONG); toast.setView(layout); final int DELAY_TIME = 2000; new Handler().postDelayed(new Runnable() { @Override public void run() { toast.cancel(); } }, DELAY_TIME); toast.show(); } ``` 在需要显示Toast的地方调用: ``` java showCustomToast(getApplicationContext(), "自定义Toast显示时间"); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值