bugly集成了Tinker熱更新

介紹

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

爲何使用Bugly熱更新?git

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

    第一步:添加插件依賴

    工程根目錄下「build.gradle」文件中添加:github

    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.7app

     

    tinker-support 1.0.3 對應 tinker 1.7.6ide

     

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

    第二步:集成SDK

    gradle配置gradle

    在app module的「build.gradle」文件中添加(示例配置):ui

     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"/>

    注意:若是你也想使用升級功能,你必需要進行二、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.**{*;}

    使用範例

    你們若是想測試驗證熱更新能力,請仔細查看如下文檔:

    熱更新使用範例

  • 官方文檔
相關文章
相關標籤/搜索