1. 程式人生 > >熱更新-Bugly-Tinker使用詳解

熱更新-Bugly-Tinker使用詳解

Bugly熱更新是基於Tinker使用的。

為什麼使用Bugly呢,因為他目前還沒有收費偷笑

費話不多說了,言歸正傳

使用教程,跟著步驟一步一步教你整合

gradle整合方式

1、新增依賴

compile 'com.tencent.bugly:crashreport_upgrade:1.3.3'//版本號可替換為latest.release表示最新版本
compile 'com.android.support:multidex:1.0.2'//這是谷歌官方提供的分包外掛,必須依賴
注意:Bugly的bug跟蹤功能同樣有。

2、新增Bugly外掛

在專案的gradle中新增外掛,位置如下:

classpath 'com.tencent.bugly:tinker-support:1.1.0'


3、新增tinker的gradle配置,名稱:tinker-support.gradle(名字可自定義),將下面的內容複製貼上即可,如下:

重要的東西寫在前面:下面的bakPath路徑可自定義,打正式包或者debug都會在此路徑下生成一些資訊(自己一看便知)

apply plugin: 'com.tencent.bugly.tinker-support'
def bakPath = file("D:/Tinker/bakApk/")//這裡是配置的路徑

/**
 * 此處填寫每次構建生成的基準包目錄
 */
def baseApkDir = "app-0102-10-00-23"
/**
 * 對於外掛各引數的詳細解析請參考
*/ tinkerSupport { // 開啟tinker-support外掛,預設值true enable = true // tinkerEnable功能開關 tinkerEnable = true // 自動生成tinkerId, 你無須關注tinkerId,預設為false autoGenerateTinkerId = true // 指定歸檔目錄,預設值當前module的子目錄tinker autoBackupApkDir = "${bakPath}" // 是否啟用覆蓋tinkerPatch配置功能,預設值false // 開啟後tinkerPatch配置不生效,即無需新增tinkerPatch
overrideTinkerPatchConfiguration = true // 編譯補丁包時,必需指定基線版本的apk,預設值為空 // 如果為空,則表示不是進行補丁包的編譯 // @{link tinkerPatch.oldApk } baseApk = "${bakPath}/${baseApkDir}/app-release.apk" // baseApk = "${bakPath}/${baseApkDir}/app-debug.apk" // 對應tinker外掛applyMapping baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-release-mapping.txt" // baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-debug-mapping.txt" // 對應tinker外掛applyResourceMapping baseApkResourceMapping = "${bakPath}/${baseApkDir}/app-release-R.txt" // baseApkResourceMapping = "${bakPath}/${baseApkDir}/app-debug-R.txt" // 構建基準包跟補丁包都要修改tinkerId,主要用於區分 tinkerId = "1.0.3.18010210-base" // 打多渠道補丁時指定目錄 // buildAllFlavorsDir = "${bakPath}/${baseApkDir}" // 是否使用加固模式,預設為false // isProtectedApp = true // 是否採用反射Application的方式整合,無須改造Application enableProxyApplication = true // 支援新增Activity supportHotplugComponent = true } /** * 一般來說,我們無需對下面的引數做任何的修改 * 對於各引數的詳細介紹請參考: * https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97 */ tinkerPatch { tinkerEnable = true ignoreWarning = false useSign = false 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 = "D:/Tinker/path" } buildConfig { keepDexApply = false // tinkerId = "base-2.0.1" } }
4、將剛剛新建的gradle配置放進主model-app中,如下:
// 依賴外掛指令碼
apply from: 'tinker-support.gradle'


5、新建一個補丁的儲存路徑,待會兒會在manifest中配置,放在model中沒試過,試過了再更新,如下:


<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- /storage/emulated/0/Download/com.bugly.upgrade.demo/.beta/apk-->
<external-path name="beta_external_path" path="Download/"/>
<!--/storage/emulated/0/Android/data/com.bugly.upgrade.demo/files/apk/-->
<external-path name="beta_external_files_path" path="Android/data/"/>
</paths>
6、必不可少的manifest配置,如下:
<!-- Bugly升級SDK配置開始  -->
<activity
android:name="com.tencent.bugly.beta.ui.BetaActivity"
android:theme="@android:style/Theme.Translucent" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="org.chriszou.redpackthelper.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
    <meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<!-- Bugly升級SDK配置結束-->
注意:這一步需要注意fileProvider的authorities配置,規則為:包名+“.fileProvider”。包名此處可更新為唯一的標識 

7、這是最後一步啦,在Application中初始化Bugly,我是自己封裝的Application,需要自己改下繼承,比如繼承Application,如下:

package org.chris.quick.b;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.StrictMode;
import android.widget.Toast;
import com.tencent.bugly.Bugly;
import com.tencent.bugly.beta.Beta;
import com.tencent.bugly.beta.interfaces.BetaPatchListener;
import com.tencent.bugly.beta.upgrade.UpgradeStateListener;
import org.chris.quick.m.Log;
import java.util.Locale;
/**
 * Created by zoulx on 2017/11/20.
 */
public class BaseTinkerApplication extends BaseApplication {
    private static final String TAG = "BaseTinkerApplication";
@Override
public void onInit() {
        setStrictMode();
}
    @Override
public void initBuggly() {
        // 設定是否開啟熱更新能力,預設為true
Beta.enableHotfix = true;
// 設定是否自動下載補丁
Beta.canAutoDownloadPatch = true;
// 設定是否提示使用者重啟
Beta.canNotifyUserRestart = true;
// 設定是否自動合成補丁
Beta.canAutoPatch = true;
/**
         *  全量升級狀態回撥
         */
Beta.upgradeStateListener = new UpgradeStateListener() {
            @Override
public void onUpgradeFailed(boolean b) {

            }

            @Override
public void onUpgradeSuccess(boolean b) {

            }

            @Override
public void onUpgradeNoVersion(boolean b) {
                Toast.makeText(getApplicationContext(), "最新版本", Toast.LENGTH_SHORT).show();
}

            @Override
public void onUpgrading(boolean b) {
                Toast.makeText(getApplicationContext(), "onUpgrading", Toast.LENGTH_SHORT).show();
}

            @Override
public void onDownloadCompleted(boolean b) {

            }
        };
/**
         * 補丁回撥介面,可以監聽補丁接收、下載、合成的回撥
         */
Beta.betaPatchListener = new BetaPatchListener() {
            @Override
public void onPatchReceived(String patchFileUrl) {
                Toast.makeText(getApplicationContext(), patchFileUrl, Toast.LENGTH_SHORT).show();
}

            @Override
public void onDownloadReceived(long savedLength, long totalLength) {
                Toast.makeText(getApplicationContext(), String.format(Locale.getDefault(),
"%s %d%%",
Beta.strNotificationDownloading,
(int) (totalLength == 0 ? 0 : savedLength * 100 / totalLength)), Toast.LENGTH_SHORT).show();
}

            @Override
public void onDownloadSuccess(String patchFilePath) {
                Toast.makeText(getApplicationContext(), patchFilePath, Toast.LENGTH_SHORT).show();
//                Beta.applyDownloadedPatch();
}

            @Override
public void onDownloadFailure(String msg) {
                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}

            @Override
public void onApplySuccess(String msg) {
                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}

            @Override
public void onApplyFailure(String msg) {
                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}

            @Override
public void onPatchRollback() {
                Toast.makeText(getApplicationContext(), "onPatchRollback", Toast.LENGTH_SHORT).show();
}
        };
        long start = System.currentTimeMillis();
// 這裡實現SDK初始化,appId替換成你的在Bugly平臺申請的appId,除錯時將第三個引數設定為true
Bugly.init(this, getBugglyAppId(), true);
        long end = System.currentTimeMillis();
Log.e("init time--->", end - start + "ms");
}



    @Override
protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
//MultiDex.install(base);//此處需要初始化分包,一定要在Bugly之前
        // 安裝tinker
Beta.installTinker();
}


    @TargetApi(9)
    protected void setStrictMode() {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
}
}

注意:將自己的bugly ID填入初始化就可以了,這樣子熱更新與Bug跟蹤都能正常使用

8、最後是混淆忽略啦

# Bugly混淆規則
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}

# 避免影響升級功能,需要keep住support包的類
-keep class android.support.**{*;}
完成以上8步那麼就將Bugly整合完畢了。

-------------------------------------------------------我是分割線----------------------------------------------------------------

整合完了,是不是要使用呢?整合So easy,但是我在使用過程中,遇到坑呀,搞死個人呢。

下面是使用步驟

1、準備有問題的包。

先打個正式包,如果是自己用其他渠道打包,可以忽略這一步,如下:


打完了之後就可以在剛才配置的路徑下檢查是否有東西喲(三個檔案),會根據當前時間生成資料夾,如下:


注意:我是打的正式包,所以是release,如果是debug包,那名稱就是debug樣子的。

2、修復有問題的包,將剛剛打的包路徑"app-0108-12-18-26",填入bugly配置gradle中,並將tinkerId改為1.0.3.18010120-patch,如下:


注意:如果是Debug方式打的包,需要修改下面的baseApk、baseApkProguardMapping、baseApkResourceMapping的檔名稱為路徑下面的debug名稱即可

    baseApk = "${bakPath}/${baseApkDir}/app-release.apk"
//    baseApk =  "${bakPath}/${baseApkDir}/app-debug.apk"
    // 對應tinker外掛applyMapping
baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-release-mapping.txt"
//    baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-debug-mapping.txt"
    // 對應tinker外掛applyResourceMapping
baseApkResourceMapping = "${bakPath}/${baseApkDir}/app-release-R.txt"
3、上面兩步都完成了之後,就開始打補丁了。

我們之前是打的正式包,所以這裡選擇就是正式補丁,不然會報錯。如下:


4、補丁打好了,會在build資料夾輸出,如下:


4、補丁打好了,那麼就剩下最後一步了,將patch_signed_7zip.apk上傳至bugly平臺即可,去bugly平臺上傳就行了。

注意:上傳時會要求啟動基線包,意思就是把剛剛有問題的包,裝在手機上面啟動一下,一次即可,如果上傳還是提示找不到基本包,那就多啟動幾次就行啦。如果反覆試都不行,就得檢查環境是否整合成功了。重頭再檢查一下是否步驟操作完成了。

到此bugly熱更新就結束了。