AS--›Bugly热更新接入脚本

版权声明:欢迎转载,转载请注明出处-->http://blog.csdn.net/angcyo https://blog.csdn.net/angcyo/article/details/82977237

Bugly热更新接入脚本

优先阅读

Bugly Android热更新使用指南

Bugly Android热更新详解

Bugly Android 热更新常见问题

热更新API接口

使用说明

1. 复制脚本到工程

2. 在工程根目录下的build.gradle配置


apply from: './bugly/bugly_config.gradle'

3. 在模块application目录下的build.gradle配置

支持同时在applicationlibrary中设置, 脚本自动区分.


apply from: '../bugly/bugly_config.gradle'

到此脚本配置完成, 打包时可以生成带有tinkerId的基准包和app-release-R.txtapp-release-mapping.txt文件(如果有)

4. 当你在打包apk时, 根目录下的buglyApk目录会收集基准包和补丁需要的app-release-R.txtapp-release-mapping.txt文件(如果有)

5.生成补丁

生成补丁之前, 一定需要:

  1. 带有tinkerId的基准包.(配置脚本后, 生成的apk都会有)
  2. app-release-R.txt文件(有资源就会有),app-release-mapping.txt文件(混淆后有)

配置脚本:

bugly_patch_apk_dir:基准包和那2个文件所在的相对路径(默认在根目录/buglyApk中), 打包APK后, 会自动生成.

bugly_patch_apk_name:需要打补丁的基准包名称(包含后缀的文件名,相对于bugly_patch_apk_dir的路径)

执行脚本,即可生成补丁:

补丁会出现在根目录/buglyApk中, 和bugly_patch_apk_dir中.各有一份.

之后在
Bugly后台上传补丁,立即下发,即可.

脚本干了啥?

针对官方的tinker-support.gradle做了一组封装,完全可以摒弃不用.
提供了一些便利性:

  • 根目录的build.grale和模块的build.grale统一配置,脚本自动区分
  • 将配置参数, 统一到bugly_config.gradle脚本文件入口,方便修改
  • 自动从build/outputs目录收集补丁文件到指定目录下, 省去查找消耗
  • 自动标志创建过补丁文件的基准包目录, 防止被误删.
  • 自动清理多次打包tinker-support.gradle收集的冗余文件.

已验证

  • 单个类修改
  • 新增/修改String资源
  • 新增普通类

ToDo

  • 多渠道打包测试 美团 walle 通过
  • 加固打包测试 2018-9-20 360, 乐固 通过
  • 新增四大组件测试 Activity通过
  • so文件修改测试 需要使用Beta.loadLibrary("mylib")
  • 新增类测试 Activity, View, 普通类, 通过

注意 QA

  1. Debug 时不支持instant run
  2. 补丁的检查会在杀掉进程重启后执行; 补丁的生效, 会在下一次重启.
  3. 当看到log, I/CrashReport: Tinker patch success, result: 表示补丁生效.重启可看到效果
//补丁更新相关日志
com.angcyo.buglydemo I/CrashReport: onUpgradeReceived: title: 
    newFeature: 测试9
    publishTime: 0
    publishType: 0
    appBasicInfo: {
        appId: 44e2baffd2
        platformId: 1
        versionCode: 0
        versionName: null
        buildNo: 0
        iconUrl: null
        apkId: 0
        channelId: null
        md5: 2e753f98f482b48cc2d218d8fb8237915149a0e0
        sdkVer: 
        bundleId: null
    }
    apkBaseInfo: {
        apkMd5: 2e753f98f482b48cc2d218d8fb8237915149a0e0
        apkUrl: https://s.beta.gtimg.com/rdmimg/hot_patch/44e2baffd2/226190d8-08d3-4cac-90c0-7ae4561ea6af.zip
        manifestMd5: 
        fileSize: 7071
        signatureMd5: 
    }
    updateStrategy: 0
    popTimes: 0
    popInterval: 0
    diffApkInfo: {
        null}
    netType: null
    reserved: 1, {
        (
            H2
            5
        )
    }
    strategyId: 377c79b8-3d99-4072-a19a-95ed401842ac
    status: 1
    updateTime: 1537155350000
    updateType: 3
     [type: 3]
com.angcyo.buglydemo W/CrashReport: task start com.tencent.bugly.proguard.t
com.angcyo.buglydemo D/CrashReport: [Database] insert dl_1002 success.
com.angcyo.buglydemo I/chatty: uid=10168(com.angcyo.buglydemo) BETA_SDK_DOWNLO identical 1 line
com.angcyo.buglydemo D/CrashReport: [Database] insert dl_1002 success.
com.angcyo.buglydemo I/CrashReport: patch download success !!!
com.angcyo.buglydemo D/CrashReport: copy /data/user/0/com.angcyo.buglydemo/app_tmpPatch/226190d8-08d3-4cac-90c0-7ae4561ea6af.zip to /data/user/0/com.angcyo.buglydemo/app_tmpPatch/tmpPatch.apk success!
    delete temp file
com.angcyo.buglydemo D/Tinker.TinkerManager: onDownloadSuccess.
com.angcyo.buglydemo D/Tinker.TinkerManager: check if has new patch.
com.angcyo.buglydemo D/Tinker.TinkerManager: has new patch.
com.angcyo.buglydemo D/Tinker.TinkerManager: starting patch.
com.angcyo.buglydemo I/Tinker.TinkerPatchListener: receive a patch file: /data/user/0/com.angcyo.buglydemo/app_tmpPatch/tmpPatch.apk, file size:7071
com.angcyo.buglydemo I/Tinker.TinkerPatchListener: get platform:null
com.angcyo.buglydemo I/Tinker.TinkerPatchService: run patch service by job scheduler.
com.angcyo.buglydemo I/Tinker.TinkerPatchService: check if patch service is running.
com.angcyo.buglydemo W/Tinker.TinkerPatchService: patch service is not running, retry with IntentService.
com.angcyo.buglydemo I/Tinker.TinkerPatchService: run patch service by intent service.
com.angcyo.buglydemo I/Tinker.TinkerPatchService: successfully start patch service with IntentService.
com.angcyo.buglydemo I/Tinker.TinkerResultService: TinkerResultService receive result: 
    PatchResult: 
    isSuccess:true
    rawPatchFilePath:/data/user/0/com.angcyo.buglydemo/app_tmpPatch/tmpPatch.apk
    costTime:5513
    patchVersion:f0148dd75d2538d441b138e6f5b75567
com.angcyo.buglydemo I/Process: Sending signal. PID: 15427 SIG: 9
com.angcyo.buglydemo W/Tinker.DefaultTinkerResultService: deleteRawPatchFile rawFile path: /data/user/0/com.angcyo.buglydemo/app_tmpPatch/tmpPatch.apk
com.angcyo.buglydemo I/CrashReport: Tinker patch success, result: 
    PatchResult: 
    isSuccess:true
    rawPatchFilePath:/data/user/0/com.angcyo.buglydemo/app_tmpPatch/tmpPatch.apk
    costTime:5513
    patchVersion:f0148dd75d2538d441b138e6f5b75567
com.angcyo.buglydemo I/Tinker.PatchFileUtil: safeDeleteFile, try to delete path: /data/user/0/com.angcyo.buglydemo/app_tmpPatch/tmpPatch.apk
com.angcyo.buglydemo I/Tinker.TinkerResultService: tinker wait screen to restart process
com.angcyo.buglydemo D/Tinker.DefaultAppLike: onTrimMemory level:5

Bugly SDK 简要接入说明

enableProxyApplication = false 的情况

1.自定义Application

public class BuglyApplication extends TinkerApplication {
    public BuglyApplication() {
        super(ShareConstants.TINKER_ENABLE_ALL,
        "com.angcyo.ApplicationLike",//真正自己自定义的Application
        "com.tencent.tinker.loader.TinkerLoader", 
        false);
    }
}

//参数解析
参数1:tinkerFlags 表示Tinker支持的类型 dex only、library only or all suuport,default: TINKER_ENABLE_ALL
参数2:delegateClassName Application代理类 这里填写你自定义的ApplicationLike
参数3:loaderClassName Tinker的加载器,使用默认即可
参数4:tinkerLoadVerifyFlag 加载dex或者lib是否验证md5,默认为false

2.自定义ApplicationLike

public class SampleApplicationLike extends DefaultApplicationLike {

    public static final String TAG = "Tinker.SampleApplicationLike";

    public SampleApplicationLike(Application application, int tinkerFlags,
            boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime,
            long applicationStartMillisTime, Intent tinkerResultIntent) {
        super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
    }


    @Override
    public void onCreate() {
        super.onCreate();
        // 这里实现SDK初始化,appId替换成你的在Bugly平台申请的appId
        // 调试时,将第三个参数改为true
        Bugly.init(getApplication(), "xxx", false);
    }


    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void onBaseContextAttached(Context base) {
        super.onBaseContextAttached(base);
        // you must install multiDex whatever tinker is installed!
        MultiDex.install(base);
        
        //开发设备
        Bugly.setIsDevelopmentDevice(base, !"release".equalsIgnoreCase(BuildConfig.BUILD_TYPE));
        
        // 安装tinker
        // TinkerManager.installTinker(this); 替换成下面Bugly提供的方法
        Beta.installTinker(this);
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public void registerActivityLifecycleCallback(Application.ActivityLifecycleCallbacks callbacks) {
        getApplication().registerActivityLifecycleCallbacks(callbacks);
    }

}

enableProxyApplication = true 的情况

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        // 这里实现SDK初始化,appId替换成你的在Bugly平台申请的appId
        // 调试时,将第三个参数改为true
        Bugly.init(this, "xxx", false);
    }

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


        // 安装tinker
        Beta.installTinker();
    }

}

源码地址


群内有各(pian)种(ni)各(jin)样(qun)的大佬,等你来撩.

联系作者

点此快速加群

请使用QQ扫码加群, 小伙伴们都在等着你哦!

关注我的公众号, 每天都能一起玩耍哦!

猜你喜欢

转载自blog.csdn.net/angcyo/article/details/82977237