Bugly 熱修復(fù)

1.導(dǎo)入依賴及插件


根Gradle
moduel? Gradle
moduel??Gradle

2.配置插件腳本?? tinker-support.gradle

applyplugin:'com.tencent.bugly.tinker-support'

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

def baseApkDir ="app-0825-11-40-17"

tinkerSupport {

? ? enable =true??// 開啟tinker-support插件,默認(rèn)值true

? autoBackupApkDir ="${bakPath}"??? // 指定歸檔目錄,默認(rèn)值當(dāng)前module的子目錄tinker

? ? //建議設(shè)置true,用戶就不用再自己管理tinkerId的命名,插件會為每一次構(gòu)建的base包自動生成唯一的tinkerId

? ? autoGenerateTinkerId =true

? ? //tinkerId必須保證唯一性,如果兩個base包的tinkerid是一樣的,并且都聯(lián)網(wǎng)激活了,那么后續(xù)補(bǔ)丁上傳到后臺的時候會出現(xiàn)匹配錯誤

? ? tinkerId ="if autoGenerateTinkerId=true ,no need set here"

? ? // 是否啟用覆蓋tinkerPatch配置功能,默認(rèn)值false

// 開啟后tinkerPatch配置不生效,即無需添加tinkerPatch

? ? overrideTinkerPatchConfiguration =true

? ? // 編譯補(bǔ)丁包時,必需指定基線版本的apk,默認(rèn)值為空

// 如果為空,則表示不是進(jìn)行補(bǔ)丁包的編譯

// @{link tinkerPatch.oldApk }

? ? baseApk ="${bakPath}/${baseApkDir}/app-release.apk"

? ? // 對應(yīng)tinker插件applyMapping

? ? baseApkProguardMapping ="${bakPath}/${baseApkDir}/app-release-mapping.txt"

? ? // 對應(yīng)tinker插件applyResourceMapping

? ? baseApkResourceMapping ="${bakPath}/${baseApkDir}/app-release-R.txt"

//? ? buildAllFlavorsDir = "${bakPath}/${baseApkDir}"

// 是否開啟加固模式,默認(rèn)為false

? ? isProtectedApp =true

? ? enableProxyApplication =false

? ? supportHotplugComponent =true

}

/**

* 一般來說,我們無需對下面的參數(shù)做任何的修改

*/

tinkerPatch {

//oldApk ="${bakPath}/${appName}/app-debug.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-patch"

//applyMapping = "${bakPath}/${appName}/app-debug-mapping.txt" //? 可選,設(shè)置mapping文件,建議保持舊apk的proguard混淆方式

//applyResourceMapping = "${bakPath}/${appName}/app-debug-R.txt" // 可選,設(shè)置R.txt文件,通過舊apk文件保持ResId的分配

? ? }

}

3.配置AndroidMainfirst

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<uses-permission android:name="android.permission.INTERNET"/>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

AndroidMainfirst
provider_paths

4.配置Application

public class SampleApplicationextends TinkerApplication {

public SampleApplication() {

super(ShareConstants.TINKER_ENABLE_ALL, "com.xx.xxx.SampleApplicationLike",

? ? ? ? ? ? ? "com.tencent.tinker.loader.TinkerLoader", false);

? ? }}

SampleApplicationLike?是Application的代理類,以前所有在Application的實(shí)現(xiàn)必須要全部拷貝到這里

public class SampleApplicationLike extends DefaultApplicationLike {

public static final StringTAG ="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();

? ? ? ? Beta.enableHotfix =true;? // 設(shè)置是否開啟熱更新能力,默認(rèn)為true

? ? ? ? Beta.canAutoDownloadPatch =true;? // 設(shè)置是否自動下載補(bǔ)丁,默認(rèn)為true

? ? ? ? Beta.canAutoPatch =true;? // 設(shè)置是否自動合成補(bǔ)丁,默認(rèn)為true

? ? ? ? Beta.canNotifyUserRestart =true;// 設(shè)置是否提示用戶重啟,默認(rèn)為false

// 補(bǔ)丁回調(diào)接口

? ? ? ? Beta.betaPatchListener =new BetaPatchListener() {

@Override

? ? ? ? ? ? public void onPatchReceived(String patchFile) {

Toast.makeText(getApplication(), "補(bǔ)丁下載地址" + patchFile, Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

@Override

? ? ? ? ? ? public void onDownloadReceived(long savedLength, long totalLength) {

Toast.makeText(getApplication(),

? ? ? ? ? ? ? ? ? ? ? ? String.format(Locale.getDefault(), "%s %d%%",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Beta.strNotificationDownloading,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (int) (totalLength ==0 ?0 : savedLength *100 / totalLength)),

? ? ? ? ? ? ? ? ? ? ? ? Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

@Override

? ? ? ? ? ? public void onDownloadSuccess(String msg) {

Toast.makeText(getApplication(), "補(bǔ)丁下載成功", Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

@Override

? ? ? ? ? ? public void onDownloadFailure(String msg) {

Toast.makeText(getApplication(), "補(bǔ)丁下載失敗", Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

@Override

? ? ? ? ? ? public void onApplySuccess(String msg) {

Toast.makeText(getApplication(), "補(bǔ)丁應(yīng)用成功", Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

@Override

? ? ? ? ? ? public void onApplyFailure(String msg) {

Toast.makeText(getApplication(), "補(bǔ)丁應(yīng)用失敗", Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

@Override

? ? ? ? ? ? public void onPatchRollback() {

}

};

? ? ? ? // 設(shè)置開發(fā)設(shè)備,默認(rèn)為false,上傳補(bǔ)丁如果下發(fā)范圍指定為“開發(fā)設(shè)備”,需要調(diào)用此接口來標(biāo)識開發(fā)設(shè)備

? ? ? ? Bugly.setIsDevelopmentDevice(getApplication(), true);

? ? ? ? // 多渠道需求塞入

// String channel = WalleChannelReader.getChannel(getApplication());

// Bugly.setAppChannel(getApplication(), channel);

// 這里實(shí)現(xiàn)SDK初始化,appId替換成你的在Bugly平臺申請的appId

? ? ? ? Bugly.init(getApplication(), "d9e0ae879b", true);

? ? }

@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);

? ? ? ? // TODO: 安裝tinker

? ? ? ? Beta.installTinker(this);

? ? }

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)

public void registerActivityLifecycleCallback(

Application.ActivityLifecycleCallbacks callbacks) {

getApplication().registerActivityLifecycleCallbacks(callbacks);

? ? }

@Override

? ? public void onTerminate() {

super.onTerminate();

? ? ? ? Beta.unInit();

? ? }

}

MainActivity中添加

override fun onBackPressed() {

super.onBackPressed()

Log.e("MainActivity", "onBackPressed")

Beta.unInit()

}

5.打包及生成補(bǔ)丁

1.打包(未發(fā)現(xiàn)bug?補(bǔ)丁生成之前):


2.修復(fù)bug 生成補(bǔ)丁

生成的補(bǔ)丁包在build/outputs/patch目錄下:


6.上傳補(bǔ)丁及修復(fù)


打開應(yīng)用后程序關(guān)閉后臺后再次啟動時自動顯示:(補(bǔ)丁剛上傳之后需等待10分左右會有結(jié)果)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容