【詳細】Android熱更新Bugly整合配置

ppjunSpirit發表於2018-02-26

上一篇文章說道tinker的熱更新,可是少了點補丁包的管理,這一篇文章介紹的bugly就是增強版的,更加方便你整合tinker和包括了補丁包的後臺管理。 為什麼使用 Bugly 熱更新?

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

Bugly下面我們用1.3.4版本的bugly來開發。

1.申請appid

去官網Bugly官網 申請appid比如asd778asd89,如果你之前應用bugly的異常上報就不用再申請appid。用的是同一個appid。

2.新增bugly外掛

在專案的root目錄下的build.gradle

classpath "com.tencent.bugly:tinker-support:1.1.1"
複製程式碼

在app/build.gralde

android{
    ...
    defaultConfig{
        //開啟dex分包
        multiDexEnabled true
    }

    dexOption{
        //大專案模式
        jumboMode true
        maxProcessCount 4
        javaMaxHeapSize "2g"
    }
    //配置好籤名
   signingConfigs {
        release {
            keyAlias 'xx'
            keyPassword 'xx'
            storeFile file('../app/xxx.jks')
            storePassword 'x'
            v1SigningEnabled true
            v2SigningEnabled true

        }
   }
   //使用你的簽名
     buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }

}

dependiences{
       implementation 'com.tencent.bugly:crashreport_upgrade:1.3.4'
       implementation 'com.android.support:multidex:1.0.2'
}
複製程式碼

如果你的專案之前使用了bugly的crash包就要去掉,因為crashreport_upgrade包裡面包含了crash。不然會提示program is already.

3. 建立tinker-support.gradle檔案

目標地址app/tinker-support.gradle,然後在app/build.gradle申請加入apply from: 'tinker-support.gradle'

這樣子完成了70%。

//請求外掛
apply plugin: 'com.tencent.bugly.tinker-support'
//基準包路徑
def bakPath=file("${buildDir}/bakApk/")
//基準包父目錄
def baseApkDir="app-0224-14-03-02"

//基準包的tinkerid
//def myTinkerId="base-"+"1.0"
//補丁包的tinkerid,每釋出一個補丁包依次疊加一次補丁版本號(比如0.0->0.1)
def myTinkerId="patch-"+"1.0"+".0.1"

tinkerSupport{
    //是否啟動熱修復,開發階段設定為false
    enable=true
    //app要不要加固
    isProtectedApp =false
    //反射獲取application
    enableProxyApplication=false
    //支援新增activity嗎
    supportHotplugComponent=true
    autoBackupApkDir="${bakPath}"
    //autoGenerateTinkerId = true
    overrideTinkerPatchConfiguration =true
    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="${myTinkerId}"
}
/**
 * 一般來說,我們無需對下面的引數做任何的修改
 * 對於各引數的詳細介紹請參考:
 * 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的分配
    }
}
複製程式碼

4. 建立ApplicationLike類

把專案的application繼承為TinkerApplciation 在建構函式呼叫父類方法比如,最後在Androidmanifest。xml的application標籤的name還是DemoApplication(繼承TinkerApplication的Applciation)

裡面有四個引數分別是

  1. 你要修復什麼內容有dex so res等,全選就是TINKER_ENABLE_ALL
  2. ApplicationLike代理Application類,正真的oncreate attachBaseContext寫在裡面
  3. tinker的類載入器,預設是它
  4. 要不要驗證md5 ,因為上文知道jar模式驗證md5很慢,所以不驗證了。
public class DemoApplication extends TinkerApplication {
    public DemoApplication() {
        super(ShareConstants.TINKER_ENABLE_ALL,
                "com.ppjun.android.tinkerinbugly.DemoApplicationLike"
        ,"com.tencent.tinker.loader.TinkerLoader",false);
    }
}
複製程式碼
public class DemoApplicationLike extends DefaultApplicationLike {
    
    public DemoApplicationLike(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();

        Beta.betaPatchListener=new BetaPatchListener() {
            @Override
            public void onPatchReceived(String s) {

            }

            @Override
            public void onDownloadReceived(long l, long l1) {

            }

            @Override
            public void onDownloadSuccess(String s) {

            }

            @Override
            public void onDownloadFailure(String s) {

            }

            @Override
            public void onApplySuccess(String s) {

            }

            @Override
            public void onApplyFailure(String s) {

            }

            @Override
            public void onPatchRollback() {

            }
        };
        Bugly.setIsDevelopmentDevice(getApplication(),true);
        Bugly.init(getApplication(),"6f399f3eeb",false);
      //把你之前onCreate的邏輯寫到這裡
        
    }

    @Override
    public void onBaseContextAttached(Context base) {
        super.onBaseContextAttached(base);
        MultiDex.install(base);
        Beta.installTinker(this);
        //把你之前applciation的attachbasecontext邏輯寫到這裡
    }

   public void  registerActivityLifecycleCallback(Application.ActivityLifecycleCallbacks callbacks){
        getApplication().registerActivityLifecycleCallbacks(callbacks);
   }

    @Override
    public void onTerminate() {
        super.onTerminate();
        Beta.unInit();
    }
}

複製程式碼
  1. 確保在onBaseContextAttached裡面分包和安裝tinker
  2. 新增registerActivityLifecycleCallback方法和onTerminate方法
  3. 在oncreate註冊你的appid

現在離完成還有10%。

剩下的就是打包了。

5. 打基準包

在tinker-support.gradle修改為基準包的tinkerId。

然後執行./gradlew assembleRelease

然後在app/build/bakApk看到一個app-0224-14-03-02 已打包時間為名字的資料夾,裡面包含了有基準包app-release.apk,基準包的R.txt 和mapping.txt。

然後你可以安裝基準包。

6.修改基準包

  1. 比如修改android.text="not patch" 改為android.text="has patch"
  2. 然後修改tinker-support.gradle的baseApkDir 。改為你剛才打基準包的父資料夾名字。比如

def baseApkDir="app-0224-14-03-02"

  1. 修改補丁包的tinkerId,每打一個補丁包補丁版本+1,補丁包的tinkerid=patch+apk版本號+補丁版本號
  2. 執行./gradlew buildTinkerPatchRelease,要和之前的打的release包對應。
  3. 在app/build/outputs/patch/得到補丁包patch_signed_7zip.apk。(**不要用outputs/apk/release/patch_signed_7zip.apk **)

7. 上傳補丁包

image.png

上傳補丁包後,目標版本會出現versionName+"."+versionCode 代表識別成功

如果上傳補丁包後,沒得到目標版本號,就是代表基準包還沒被安裝。或者安裝後沒聯網。

或者基準包沒安裝tinker,沒成功初始化tinker。 如果出現-1 -2這些錯誤碼可以到TinkerLoadResult類看到對應的原因

全文完 ) ) >

相關文章