1. 程式人生 > >Android 熱修復BugIy(建立自己專案,理解並使用它)

Android 熱修復BugIy(建立自己專案,理解並使用它)

第一步老規矩導架包

1.在專案的根目錄的配置檔案中的dependencies新增
在這裡插入圖片描述

classpath "com.tencent.bugly:tinker-support:1.1.5"

2.在module的配置檔案中新增
在這裡插入圖片描述

    // 多dex配置
    compile 'com.android.support:multidex:1.0.2'
    // 本地整合aar方式
    // compile(name: 'bugly_crashreport_upgrade-1.3.6', ext: 'aar')
    // 遠端依賴整合方式(推薦)
    compile 'com.tencent.bugly:crashreport_upgrade:1.3.6'
// 指定tinker依賴版本(注:應用升級1.3.5版本起,不再內建tinker) compile 'com.tencent.tinker:tinker-android-lib:1.9.9'

然後再新增
在這裡插入圖片描述

apply from: 'tinker-support.gradle'

3.建立tinker-support.gradle

apply plugin: 'com.tencent.bugly.tinker-support'

def bakPath = file("${buildDir}/bakApk/")

/**
 * 此處填寫每次構建生成的基準包目錄
 */
def baseApkDir =
"app-1217-17-22-37" /** * 對於外掛各引數的詳細解析請參考 */ 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 = "bugpaths-1.0.1" // 構建多渠道補丁時使用 // buildAllFlavorsDir = "${bakPath}/${baseApkDir}" // 是否啟用加固模式,預設為false.(tinker-spport 1.0.7起支援) // isProtectedApp = true // 是否開啟反射Application模式 enableProxyApplication = true // 是否支援新增非export的Activity(注意:設定為true才能修改AndroidManifest檔案) supportHotplugComponent = true } /** * 一般來說,我們無需對下面的引數做任何的修改 * 對於各引數的詳細介紹請參考: * 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的分配 } }

第二步設定許可權

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

再在application標籤中新增

        <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="com.tencent.bugly.hotfix.easy.fileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>

這時候問題來了,編譯出錯了,大概是說我們需要一個app來實現熱更新
建立之後記得在application標籤中加入下面宣告程式碼

 android:name="yuexia.com.bugiydemo.MyApplication"

第三步建立MyApplication.calss

在這裡插入圖片描述
最簡單的是上面這樣的,但是為了我自己的體驗我就要回調這些方法知道補丁的狀態

package yuexia.com.bugiydemo;

import android.app.Application;
import android.content.Context;
import android.support.multidex.MultiDex;
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 java.util.Locale;

/**
 * Created by syt98 on 2018/12/17.
 */

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        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();
            }
        };



        // 這裡實現SDK初始化,appId替換成你的在Bugly平臺申請的appId
        // 除錯時,將第三個引數改為true
        Bugly.init(this, "2382e48482", false);
    }

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

第四步寫錯誤程式碼倒基包

1.錯誤程式碼就自己想了
在這裡插入圖片描述
2.倒基包
在這裡插入圖片描述
點選後發現打的apk變成了
app-release-unsigned.apk
怎麼解決呢
解決教材
之後的流程和第一篇講的一樣
轉一

總結

基本的BugIy學習到這裡結束了
這篇主要說自己建立專案用BugIy需要注意的點:
1.建立之後記得在application標籤中加入宣告程式碼
2.app-release-unsigned.apk的解決方式
3.bugiy總的來說類似於tinker的加強版,比較方便。但還是基於類的修改需要冷啟動。有它的優勢和缺陷。

有啥不懂或者小白寫的不好的可以留言