bugly集成了Tinker熱更新


介紹

熱更新能力是Bugly為解決開發者緊急修復線上bug,而無需重新發版讓用戶無感知就能把問題修復的一項能力。Bugly目前采用微信Tinker的開源方案,開發者只需要集成我們提供的SDK就可以實現自動下載補丁包、合成、並應用補丁的功能,我們也提供了熱更新管理后台讓開發者對每個版本補丁進行管理。

為什么使用Bugly熱更新?

  • 無需關注Tinker是如何合成補丁的
  • 無需自己搭建補丁管理后台
  • 無需考慮后台下發補丁策略的任何事情
  • 無需考慮補丁下載合成的時機,處理后台下發的策略
  • 我們提供了更加方便集成Tinker的方式
  • 我們通過HTTPS及簽名校驗等機制保障補丁下發的安全性
  • 豐富的下發維度控制,有效控制補丁影響范圍
  • 我們提供了應用升級一站式解決方案

    第一步:添加插件依賴

    工程根目錄下“build.gradle”文件中添加:

    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            // tinkersupport插件, 其中lastest.release指拉取最新版本,也可以指定明確版本號,例如1.0.4
            classpath "com.tencent.bugly:tinker-support:latest.release"
        }
    }

    注意:自tinker-support 1.0.3版本起無需再配tinker插件的classpath。

    版本對應關系:

     

    tinker-support 1.0.4 對應 tinker 1.7.7

     

    tinker-support 1.0.3 對應 tinker 1.7.6

     

    tinker-support 1.0.2 對應 tinker 1.7.5(需配置tinker插件的classpath)

    第二步:集成SDK

    gradle配置

    在app module的“build.gradle”文件中添加(示例配置):

     dependencies {
    
              compile "com.android.support:multidex:1.0.1" // 多dex配置
              compile 'com.tencent.bugly:crashreport_upgrade:latest.release' // 升級SDK
    }

    在app module的“build.gradle”文件中添加

    // 依賴插件腳本
    apply from: 'tinker-support.gradle'

    tinker-support.gradle內容如下所示(示例配置):

    注:您需要在同級目錄下創建tinker-support.gradle這個文件哦。

    apply plugin: 'com.tencent.bugly.tinker-support'
    
    def bakPath = file("${buildDir}/bakApk/")
    
    /**
     * 此處填寫每次構建生成的基准包目錄
     */
    def baseApkDir = "app-0208-15-10-00"
    
    /**
     * 對於插件各參數的詳細解析請參考
     */
    tinkerSupport {
    
        // 開啟tinker-support插件,默認值true
        enable = true
    
        // 指定歸檔目錄,默認值當前module的子目錄tinker
        autoBackupApkDir = "${bakPath}"
    
        // 是否啟用覆蓋tinkerPatch配置功能,默認值false
        // 開啟后tinkerPatch配置不生效,即無需添加tinkerPatch
        overrideTinkerPatchConfiguration = true
    
        // 編譯補丁包時,必需指定基線版本的apk,默認值為空
        // 如果為空,則表示不是進行補丁包的編譯
        // @{link tinkerPatch.oldApk }
        baseApk = "${bakPath}/${baseApkDir}/app-release.apk"
    
        // 對應tinker插件applyMapping
        baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-release-mapping.txt"
    
        // 對應tinker插件applyResourceMapping
        baseApkResourceMapping = "${bakPath}/${baseApkDir}/app-release-R.txt"
    
        // 構建基准包和補丁包都要指定不同的tinkerId,並且必須保證唯一性
        tinkerId = "base-1.0.1"
    
        // 構建多渠道補丁時使用
        // buildAllFlavorsDir = "${bakPath}/${baseApkDir}"
    
        // 是否開啟反射Application模式
        enableProxyApplication = false
    
    }
    
    /**
     * 一般來說,我們無需對下面的參數做任何的修改
     * 對於各參數的詳細介紹請參考:
     * https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
     */
    tinkerPatch {
        //oldApk ="${bakPath}/${appName}/app-release.apk"
        ignoreWarning = false
        useSign = true
        dex {
            dexMode = "jar"
            pattern = ["classes*.dex"]
            loader = []
        }
        lib {
            pattern = ["lib/*/*.so"]
        }
    
        res {
            pattern = ["res/*", "r/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]
            ignoreChange = []
            largeModSize = 100
        }
    
        packageConfig {
        }
        sevenZip {
            zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
    //        path = "/usr/local/bin/7za"
        }
        buildConfig {
            keepDexApply = false
            //tinkerId = "1.0.1-base"
            //applyMapping = "${bakPath}/${appName}/app-release-mapping.txt" //  可選,設置mapping文件,建議保持舊apk的proguard混淆方式
            //applyResourceMapping = "${bakPath}/${appName}/app-release-R.txt" // 可選,設置R.txt文件,通過舊apk文件保持ResId的分配
        }
    }

    更詳細的配置項參考tinker-support配置說明

    第三步:初始化SDK

     

    enableProxyApplication = false 的情況

     

    這是Tinker推薦的接入方式,一定程度上會增加接入成本,但具有更好的兼容性。

     

    集成Bugly升級SDK之后,我們需要按照以下方式自定義ApplicationLike來實現Application的代碼(以下是示例):

     

    自定義Application

    public class SampleApplication extends TinkerApplication {
        public SampleApplication() {
            super(ShareConstants.TINKER_ENABLE_ALL, "xxx.xxx.SampleApplicationLike",
                    "com.tencent.tinker.loader.TinkerLoader", false);
        }
    }

    注意:這個類集成TinkerApplication類,這里面不做任何操作,所有Application的代碼都會放到ApplicationLike繼承類當中
    參數解析
    參數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

    我們需要您將以前的Applicaton配置為繼承TinkerApplication的類:

  • 自定義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(), "900029763", 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);
    
            // 安裝tinker
            // TinkerManager.installTinker(this); 替換成下面Bugly提供的方法
            Beta.installTinker(this);
        }
    
        @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
        public void registerActivityLifecycleCallback(Application.ActivityLifecycleCallbacks callbacks) {
            getApplication().registerActivityLifecycleCallbacks(callbacks);
        }
    
    }

    注意:tinker需要你開啟MultiDex,你需要在dependencies中進行配置compile "com.android.support:multidex:1.0.1"才可以使用MultiDex.install方法; SampleApplicationLike這個類是Application的代理類,以前所有在Application的實現必須要全部拷貝到這里,在onCreate方法調用SDK的初始化方法,在onBaseContextAttached中調用Beta.installTinker(this);

  • enableProxyApplication = true 的情況

    public class MyApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
            // 這里實現SDK初始化,appId替換成你的在Bugly平台申請的appId
            // 調試時,將第三個參數改為true
            Bugly.init(this, "900029763", false);
        }
    
        @Override
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
            // you must install multiDex whatever tinker is installed!
            MultiDex.install(base);
    
    
            // 安裝tinker
            Beta.installTinker();
        }
    
    }

    注:無須你改造Application,主要是為了降低接入成本,我們插件會動態替換AndroidMinifest文件中的Application為我們定義好用於反射真實Application的類(需要您接入SDK 1.2.2版本插件版本 1.0.3以上)。

    第四步:AndroidManifest.xml配置

    1. 權限配置

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    注意:如果你也想使用升級功能,你必須要進行2、3項的配置,而如果你只想使用熱更新能力,你只需要1項配置權限即可。

  • 2. Activity配置

    <activity
        android:name="com.tencent.bugly.beta.ui.BetaActivity"
        android:theme="@android:style/Theme.Translucent" /

    3. 配置FileProvider

    注意:如果您想兼容Android N或者以上的設備,必須要在AndroidManifest.xml文件中配置FileProvider來訪問共享路徑的文件。如果你使用的第三方庫也配置了同樣的FileProvider,你需要將第三方庫配置的路徑copy到我們配置的provider_path文件下。

     <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

    ${applicationId}請替換為您的包名,例如com.bugly.upgrade.demo。這里要注意一下,FileProvider類是在support-v4包中的,檢查你的工程是否引入該類庫。

    在res目錄新建xml文件夾,創建provider_paths.xml文件如下:

    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- /storage/emulated/0/Download/${applicationId}/.beta/apk-->
        <external-path name="beta_external_path" path="Download/"/>
        <!--/storage/emulated/0/Android/data/${applicationId}/files/apk/-->
        <external-path name="beta_external_files_path" path="Android/data/"/>
    </paths>

    這里配置的兩個外部存儲路徑是升級SDK下載的文件可能存在的路徑,一定要按照上面格式配置,不然可能會出現錯誤。

    第五步:混淆配置

    為了避免混淆SDK,在Proguard混淆文件中增加以下配置:

    -dontwarn com.tencent.bugly.**
    -keep public class com.tencent.bugly.**{*;}

    如果你使用了support-v4包,你還需要配置以下混淆規則:

    
-keep class android.support.**{*;}

    使用范例

    大家如果想測試驗證熱更新能力,請仔細查看以下文檔:

    熱更新使用范例

  • 官方文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM