原創(chuàng)不易漏设,尊重作者墨闲,轉(zhuǎn)載請(qǐng)注明出處,謝謝您
前言
集成Bugly的崩潰收集和應(yīng)用升級(jí)是很簡(jiǎn)單的郑口,但是如果要集成熱更新鸳碧,那就需要仔細(xì)閱讀文檔了,況且官方的文檔隨著SDK版本的更新有些地方是不太準(zhǔn)確的犬性,官方文檔還是很貼心瞻离,還有視頻教程,當(dāng)然視頻比較老了乒裆,更多情況是開(kāi)發(fā)者集成后出現(xiàn)很多問(wèn)題不知道如何解決套利,基于這些情況,從實(shí)際出發(fā),我將根據(jù)官方集成文檔一步步講解Bugly的熱更新集成方式肉迫,要是還學(xué)不會(huì)验辞,我倒地喝水
目錄
- 快速的集成過(guò)程(相信我,真的很快喊衫,省略掉官方文檔的廢話)
- 集成完成后的測(cè)試
- 基準(zhǔn)包的補(bǔ)丁更新
- 基準(zhǔn)包多次修復(fù)BUG后的補(bǔ)丁更新
- 多渠道打包
- 基準(zhǔn)包加固后
一跌造、快速的集成過(guò)程
以下所有步驟都極度精簡(jiǎn)官方文檔,并且依賴庫(kù)版本使用新的族购,請(qǐng)認(rèn)真看添加注釋的代碼壳贪。
步驟1:在Project的build.gradle文件中添加bugly的tinker插件
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
// 添加tinker插件支持
classpath "com.tencent.bugly:tinker-support:1.1.5"
}
步驟2:在Module的build.gradle文件中添加需要使用的依賴包
dependencies {
···
// 解決65536方法數(shù)
implementation 'com.android.support:multidex:1.0.3'
// bugly Java崩潰收集和版本更新
implementation 'com.tencent.bugly:crashreport_upgrade:1.4.0'
// bugly native 崩潰收集
implementation 'com.tencent.bugly:nativecrashreport:3.7.1'
// tinker
implementation 'com.tencent.tinker:tinker-android-lib:1.9.9'
}
以上依賴大家一看注釋就知道是做什么的,就不多闡述了
步驟3:在Module的build.gradle文件中開(kāi)啟multiDex联四、配置ndk撑碴、配置app的簽名信息
release的簽名直接使用了官方demo的簽名文件
android {
···
defaultConfig {
···
// 配置ndk撑教,根據(jù)自身情況來(lái)配置(粗略簡(jiǎn)單來(lái)講朝墩,armeabi是真機(jī),x86是模擬器)
ndk {
abiFilters 'armeabi', 'x86'//,'x86_64' ,'armeabi-v7a' , 'arm64-v8a'
}
// 開(kāi)啟multiDex伟姐,解決65536方法數(shù)
multiDexEnabled true
}
// 簽名配置
signingConfigs {
// 正式包
release {
try {
storeFile file("./keystore/release.keystore")
storePassword "testres"
keyAlias "testres"
keyPassword "testres"
} catch (ex) {
throw new InvalidUserDataException(ex.toString())
}
}
// 測(cè)試包
debug {
storeFile file("./keystore/debug.keystore")
}
}
buildTypes {
release {
minifyEnabled true // 開(kāi)啟了混淆(也可以不用開(kāi)啟收苏,默認(rèn)就是false)
signingConfig signingConfigs.release // 設(shè)置簽名文件
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
如果你開(kāi)啟了混淆,在proguard-rules.pro添加代碼如下:
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
# tinker混淆規(guī)則
-dontwarn com.tencent.tinker.**
-keep class com.tencent.tinker.** { *; }
步驟4:創(chuàng)建一個(gè)tinker-support.gradle文件愤兵,添加插件參數(shù)
參數(shù)如下鹿霸,內(nèi)容全部復(fù)制即可,一律不管···
apply plugin: 'com.tencent.bugly.tinker-support'
def bakPath = file("${buildDir}/bakApk/")
/**
* 此處填寫每次構(gòu)建生成的基準(zhǔn)包目錄
*/
def baseApkDir = "app-0525-15-05-57"
/**
* 對(duì)于插件各參數(shù)的詳細(xì)解析請(qǐng)參考
*/
tinkerSupport {
// 開(kāi)啟tinker-support插件秆乳,默認(rèn)值true
enable = true
// 指定歸檔目錄懦鼠,默認(rèn)值當(dāng)前module的子目錄tinker
autoBackupApkDir = "${bakPath}"
// 是否啟用覆蓋tinkerPatch配置功能,默認(rèn)值false
// 開(kāi)啟后tinkerPatch配置不生效屹堰,即無(wú)需添加tinkerPatch
overrideTinkerPatchConfiguration = true
// 編譯補(bǔ)丁包時(shí)肛冶,必需指定基線版本的apk,默認(rèn)值為空
// 如果為空扯键,則表示不是進(jìn)行補(bǔ)丁包的編譯
// @{link tinkerPatch.oldApk }
baseApk = "${bakPath}/${baseApkDir}/app-release.apk"
// 對(duì)應(yīng)tinker插件applyMapping
baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-release-mapping.txt"
// 對(duì)應(yīng)tinker插件applyResourceMapping
baseApkResourceMapping = "${bakPath}/${baseApkDir}/app-release-R.txt"
// 構(gòu)建基準(zhǔn)包和補(bǔ)丁包都要指定不同的tinkerId睦袖,并且必須保證唯一性
tinkerId = "patch-1.0.3"
// 構(gòu)建多渠道補(bǔ)丁時(shí)使用
// buildAllFlavorsDir = "${bakPath}/${baseApkDir}"
// 是否啟用加固模式,默認(rèn)為false.(tinker-spport 1.0.7起支持)
// isProtectedApp = true
// 是否開(kāi)啟反射Application模式
enableProxyApplication = false
// 是否支持新增非export的Activity(注意:設(shè)置為true才能修改AndroidManifest文件)
supportHotplugComponent = true
}
/**
* 一般來(lái)說(shuō),我們無(wú)需對(duì)下面的參數(shù)做任何的修改
* 對(duì)于各參數(shù)的詳細(xì)介紹請(qǐng)參考:
* 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" // 可選荣刑,設(shè)置mapping文件蛤铜,建議保持舊apk的proguard混淆方式
//applyResourceMapping = "${bakPath}/${appName}/app-release-R.txt" // 可選琉朽,設(shè)置R.txt文件,通過(guò)舊apk文件保持ResId的分配
}
}
supportHotplugComponent 在官方文檔是false,我設(shè)置成了true榜轿,注釋寫的很情況了。簡(jiǎn)單說(shuō)一下export的作用就是“是否允許外部來(lái)啟動(dòng)該activity”浪规,默認(rèn)創(chuàng)建的activity的export其實(shí)就是false摘昌。
這里只講最重要的兩個(gè)參數(shù):
baseApkDir : 填寫需要打補(bǔ)丁的基準(zhǔn)包的文件夾名稱(只能填寫基準(zhǔn)包的,后續(xù)詳情說(shuō)明)。
tinkerId :構(gòu)建基準(zhǔn)包和補(bǔ)丁包的唯一id沥匈,必須保證唯一蔗喂,補(bǔ)丁包就是根據(jù)基準(zhǔn)包的tinkerId 來(lái)找到對(duì)應(yīng)的包進(jìn)行補(bǔ)丁更新的。
其他參數(shù)真的可以不用管高帖,如果對(duì)其他參數(shù)有疑問(wèn)缰儿,點(diǎn)這里https://bugly.qq.com/docs/utility-tools/plugin-gradle-hotfix/
步驟5:在Module的build.gradle中依賴步驟4的插件
apply plugin: 'com.android.application'
// 依賴插件
apply from: 'tinker-support.gradle'
步驟6:創(chuàng)建自定義的ApplicationLike類和Application類
自定義的ApplicationLike代碼如下:
public class MyApplicationLike extends DefaultApplicationLike {
private static final String TAG = "MyApplicationLike";
public MyApplicationLike(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();
// 第二個(gè)參數(shù)為bugly申請(qǐng)的應(yīng)用appId,調(diào)試時(shí)散址,將第三個(gè)參數(shù)改為true
Bugly.init(getApplication(), "1fc5a53101", 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);
// 安裝tinker
// TinkerManager.installTinker(this); 替換成下面Bugly提供的方法
Beta.installTinker(this);
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public void registerActivityLifecycleCallback(Application.ActivityLifecycleCallbacks callbacks) {
getApplication().registerActivityLifecycleCallbacks(callbacks);
}
}
自定義的Application代碼如下:
public class MyApplication extends TinkerApplication {
public MyApplication() {
super(ShareConstants.TINKER_ENABLE_ALL, "app.fynnjason.tinkerdemo.MyApplicationLike",
"com.tencent.tinker.loader.TinkerLoader", false);
}
}
在MyApplicationLike 類中乖阵,只需要關(guān)注onCreate()方法,將所有需要在Application中初始化的代碼都放到這兒來(lái)预麸。MyApplication 類是固定寫法了瞪浸,只需要替換super的第二個(gè)參數(shù)為MyApplicationLike 的路徑即可,代碼和注釋已經(jīng)非常清楚了吏祸,相信大家都看的懂对蒲。其他的可以一律不用管。
最后一步:在AndroidManifest.xml中添加Application
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="app.fynnjason.tinkerdemo">
<application
android:name=".MyApplication" // 這里
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
到此贡翘,集成就算完成了蹈矮。有人可能要問(wèn)了,官方文檔中還需要在AndroidManifest中配置權(quán)限鸣驱、特定的Activity泛鸟、Android N的共享文件,為啥這里沒(méi)有踊东。因?yàn)樵赟DK1.3.1及以上版本北滥,可以不用進(jìn)行以上配置,aar已經(jīng)在AndroidManifest配置了闸翅,并且包含了對(duì)應(yīng)的資源文件再芋,所以我這里也不用配置了。好了缎脾,集成完畢祝闻,接下來(lái)是熱更新的重頭戲了。
二遗菠、集成完成后的測(cè)試
首先我們需要打一個(gè)基準(zhǔn)包联喘,基準(zhǔn)包相當(dāng)于就是我們的一個(gè)正式包,在tinker-support.gradle文件中辙纬,我們修改tinkerId的參數(shù)為:
tinkerId = "base-1.0.1"
tinkerId 的命名是自由的豁遭,但是為了我們規(guī)范,建議是填寫有規(guī)范性的命名(這里用base來(lái)代表基準(zhǔn)包贺拣,用patch代表補(bǔ)丁包)蓖谢,baseApkDir不用修改捂蕴,這個(gè)值在打基準(zhǔn)包時(shí)是沒(méi)有作用的。然后我們打開(kāi)Android Studio的右側(cè)邊欄(一般都是右邊)闪幽,找到Gradle工具-assembleRelease啥辨,注意不同Android Studio版本的assembleRelease位置稍有不同,例如官方文檔是2.2版本盯腌,在build目錄下溉知,而我使用的是3.3.2,在other目錄下腕够。
可以看到相似的還有assembleDebug级乍,就是打debug包的,很好理解帚湘。執(zhí)行assembleRelease玫荣,等待一會(huì)兒,我們就可以得到創(chuàng)建好的基準(zhǔn)包
這個(gè)就相當(dāng)于是我們用來(lái)上線的正式包了大诸,記住此時(shí)的文件包名(app-0525-15-05-57捅厂,app-0525-15-05-57,app-0525-15-05-57底挫,重要事情說(shuō)三遍)恒傻,把里面的app-release.apk扔到手機(jī)跑起來(lái)吧脸侥!這里需要說(shuō)一下建邓,基準(zhǔn)包必須聯(lián)網(wǎng)一次,也就是在手機(jī)上安裝一次并且打開(kāi)訪問(wèn)一次網(wǎng)絡(luò)睁枕,這樣Bugly后臺(tái)才會(huì)記錄這個(gè)基準(zhǔn)包官边,以便后續(xù)補(bǔ)丁包的下發(fā)。如果我們繼承沒(méi)有任何問(wèn)題外遇,那么我們就可以在AndroidStudio日志中找到Bugly成功的日志注簿。
可以看到tinkerId參數(shù),app版本號(hào)等信息跳仿,接下來(lái)是熱更新的步驟诡渴,也是最最關(guān)鍵的。
三菲语、基準(zhǔn)包的補(bǔ)丁更新
現(xiàn)在我們?nèi)バ薷膁emo中的信息妄辩,修改TextView的文字(比如這是修改好了一個(gè)bug)。然后回到tinker-support.gradle文件中山上,我們修改tinkerId眼耀,此時(shí)就是補(bǔ)丁包的名稱,然后再修改baseApkDir佩憾,baseApkDir填寫基準(zhǔn)包的包名哮伟,這就是上一步中三遍說(shuō)的那個(gè)包名稱干花。如圖:
然后打開(kāi)右側(cè)欄的Gradle工具欄,找到如圖所示:
雙擊成功編譯后楞黄,我們可以在如圖所示查看到補(bǔ)丁包:
上圖中第一個(gè)紅框是每次編譯都會(huì)生成的apk目錄池凄,除了基準(zhǔn)包的,其他生成的可以不用管鬼廓,這里只是圈出來(lái)說(shuō)明一下修赞。第二個(gè)框是重點(diǎn)了!只使用xxxx_7zip.apk桑阶,將這個(gè)apk上傳到Bugly的熱更新管理后臺(tái)即可柏副,具體看下圖:
上傳補(bǔ)丁文件后,會(huì)顯示目標(biāo)版本蚣录,也就是基準(zhǔn)包的版本割择,點(diǎn)擊立即下發(fā)即可,下發(fā)后等待大概十分鐘萎河、下發(fā)后等待大概十分鐘荔泳、下發(fā)后等待大概十分鐘,重要事情說(shuō)三遍虐杯,因?yàn)锽ugly下發(fā)有延遲玛歌,接下來(lái)就是驗(yàn)證補(bǔ)丁是否下載成功了,以下執(zhí)行流程一定不能錯(cuò)擎椰。
1.首先殺掉我們app的進(jìn)程
2.打開(kāi)我們的app支子,等待幾秒,查看log日志达舒,如圖(圖片來(lái)自官方文檔)
如果出現(xiàn)上面這些信息值朋,那么你的補(bǔ)丁就下發(fā)成功了
3.再次殺掉我們的app進(jìn)程
4.再次打開(kāi)我們的app,查看我們修改的內(nèi)容是否成功
這就是基本的熱更新了~如果有疑問(wèn)巩搏,請(qǐng)?jiān)u論提出
四昨登、基準(zhǔn)包多次修復(fù)BUG后的補(bǔ)丁更新
上面我們只講到了一次修復(fù)bug,如果我們基準(zhǔn)包出現(xiàn)了一次bug贯底,我們用熱更新修復(fù)了丰辣,然后我們又發(fā)現(xiàn)了一個(gè)bug,這時(shí)候我們就需要再打一次補(bǔ)丁包了禽捆,那這時(shí)候我們應(yīng)該怎么做呢笙什?我會(huì)告訴你非常簡(jiǎn)單,接著往下看:
首先我們修復(fù)好代碼睦擂,繼續(xù)來(lái)到tinker-support.gradle得湘,這里我們只需要修改tinkerId的參數(shù),第一次我們修復(fù)代碼顿仇,這里的參數(shù)為patch-1.0.1淘正,那么這一次我們就改成patch-1.0.2摆马,只要保證每次唯一就行。baseApkDir不改動(dòng)鸿吆,依然是基準(zhǔn)包的包名囤采,具體如圖所示:
然后我們使用Gradle工具欄,執(zhí)行
最后我們上傳生成好的xxx_7zip.apk到管理后臺(tái)即可惩淳,流程和之前一樣蕉毯,等待十分鐘后,我們?cè)賮?lái)測(cè)試是否成功思犁!
五代虾、多渠道打包
修修改改多次后,還是覺(jué)得官方文檔已經(jīng)寫的很好了激蹲,所以推薦大家直接閱讀官方文檔
https://buglydevteam.github.io/2017/05/15/solution-of-multiple-channel-hotpatch/#%E6%80%BB%E7%BB%93
同一版本棉磨,不同渠道中代碼不同的熱更新
有這么一種情況,同一版本下学辱,不同渠道的一部分代碼不同乘瓤,比如我們開(kāi)發(fā)的APP,在應(yīng)用寶策泣、小米衙傀、華為平臺(tái)叫微信,在OPPO萨咕、VIVO平臺(tái)叫微信聊天统抬,或者部分代碼有區(qū)別(比如刺激戰(zhàn)場(chǎng)游戲針對(duì)不同廠商優(yōu)化不同,但版本號(hào)是相同的)等等情況任洞,這時(shí)候蓄喇,我們?cè)趺磳?shí)現(xiàn)同一個(gè)BUG的熱更新呢发侵?
解決方案:
1.首先是基準(zhǔn)包的生成交掏,我們需要將渠道分組,完全相同代碼的為一組刃鳄,在tinker-support.gradle文件中盅弛,設(shè)置該組唯一的tinkerId,例如我們把
應(yīng)用寶叔锐、小米挪鹏、華為平臺(tái)設(shè)置為base-1.0.1-a,將OPPO愉烙、VIVO平臺(tái)設(shè)置為base-1.0.1-b讨盒,然后進(jìn)行多渠道打包,最后我們可以得到每組的bakApk中的基準(zhǔn)包的內(nèi)容步责,需要說(shuō)的是返顺,美團(tuán)多渠道打包的命令每次執(zhí)行都會(huì)刪掉上次多渠道打包的內(nèi)容禀苦,所以大家要每次記得要備份一下該組的基準(zhǔn)包!一定要備份遂鹊!記得備份振乏!
然后就可以將多渠道打包的apk上線了。
2.現(xiàn)在我們來(lái)生成每組的補(bǔ)丁秉扑,將bug修復(fù)后慧邮,我們依舊回到tinker-support.gradle文件中,針對(duì)不同組的補(bǔ)丁舟陆,需要設(shè)置不同的tinkerId误澳,例如應(yīng)用寶、小米秦躯、華為平臺(tái)設(shè)置為patch-1.0.1-a脓匿,將OPPO、VIVO平臺(tái)設(shè)置為patch-1.0.1-b宦赠,其中bakApk的參數(shù)就填寫該組的包名即可陪毡,相信大家應(yīng)該明白這個(gè)意思。接著我們生成應(yīng)用寶勾扭、小米毡琉、華為平臺(tái)的補(bǔ)丁后,我們將補(bǔ)丁上傳到Bugly后臺(tái)管理上發(fā)布妙色,然后繼續(xù)生成OPPO桅滋、VIVO平臺(tái)的補(bǔ)丁包,再上傳到Bugly后臺(tái)管理上發(fā)布身辨。這樣丐谋,我們就實(shí)現(xiàn)了同一版本下,部分代碼不同下的熱更新效果了煌珊。
PS:只能共存最多5組補(bǔ)丁号俐,只能共存最多5組補(bǔ)丁,只能共存最多5組補(bǔ)抖ㄢ帧吏饿!也就是只能分成最多5組喲
六、基準(zhǔn)包的加固
確實(shí)很簡(jiǎn)單蔬浙,畢竟大家都使用的第三方加固工具猪落,官方文檔也沒(méi)有特意去寫文檔,這里就摘錄一下畴博,實(shí)際效果也確實(shí)如此笨忌。
需要集成升級(jí)SDK版本1.3.0以上版本才支持加固。
經(jīng)過(guò)測(cè)試的加固產(chǎn)品:
- 騰訊樂(lè)固
- 愛(ài)加密
- 梆梆加固
- 360加固(SDK 1.3.1之后版本支持)
其他產(chǎn)品需要大家進(jìn)行驗(yàn)證俱病。
1.設(shè)置isProtectedApp參數(shù)
在tinker-support配置當(dāng)中設(shè)置isProtectedApp = true官疲,表示你要打加固的的apk杂曲。 是否使用加固模式,僅僅將變更的類合成補(bǔ)丁袁余。注意擎勘,這種模式僅僅可以用于加固應(yīng)用中。
2.將基準(zhǔn)包進(jìn)行加固
如果你的app需要進(jìn)行加固颖榜,你需要將你打出的基準(zhǔn)包上傳到具體的加固平臺(tái)進(jìn)行加固棚饵,例如樂(lè)固,加固完成之后需要對(duì)apk進(jìn)行重簽名:
jarsigner -verbose -keystore <YOUR_KEYSTORE> -signedjar <SIGNED_APK> <UNSIGNED_APK> <KEY_ALIAS>
以上命令說(shuō)明:
-verbose:指定生成詳細(xì)輸出
-keystore:指定證書(shū)存儲(chǔ)路徑
-signedjar:改選項(xiàng)的三個(gè)參數(shù)分別為簽名后的apk包掩完、未簽名的apk包噪漾、數(shù)字證書(shū)別名
示例:
jarsigner -verbose -keystore keystore/release.keystore -signedjar app-release-signed.apk app-release.encrypted.apk testres
如果你使用的加固產(chǎn)品提供了GUI的加固和簽名工具,可以通過(guò)工具來(lái)進(jìn)行加固和簽名且蓬。
3.根據(jù)未加固的基準(zhǔn)包生成補(bǔ)丁包
打patch包的操作跟普通打包方式一致欣硼。
注意:這里指定的基線版本是未加固的版本。
4.測(cè)試驗(yàn)證
測(cè)試驗(yàn)證的版本是經(jīng)過(guò)加固并且已經(jīng)重簽名后的apk恶阴,安裝到測(cè)試設(shè)備并上報(bào)聯(lián)網(wǎng)诈胜,其他操作與普通打包無(wú)異。
其他問(wèn)題
美團(tuán)多渠道包使用加固工具后冯事,渠道信息null的解決辦法
https://github.com/Jay-Goo/ProtectedApkResignerForWalle
多渠道加固的新方式(樂(lè)固篇)
大多數(shù)情況我們的APP都是需要多渠道打包和加固的焦匈,如果按照之前的方式使用美團(tuán)打多渠道包并且加固再解決加固后的渠道信息,這是一個(gè)挺麻煩的事昵仅,下面介紹一種更簡(jiǎn)單的方法缓熟,不妨看看:
1.使用普通方式打一個(gè)基準(zhǔn)包
2.將基準(zhǔn)包直接使用樂(lè)固的簽名加固和多渠道輸出
3.運(yùn)行樂(lè)固生成的多渠道apk后打一個(gè)基準(zhǔn)包的補(bǔ)丁包
4.上傳補(bǔ)丁包,完成
是不是覺(jué)得很像目錄三的熱更新方式摔笤?其他加固工具方法類似够滑,大家可以自行測(cè)試~
結(jié)論
如果文章對(duì)你有幫助,點(diǎn)個(gè)贊支持一下~
附錄:
官方文檔:https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix/?v=20181014122344
官方文檔中熱更新的常見(jiàn)問(wèn)題:https://bugly.qq.com/docs/user-guide/faq-android-hotfix/?v=20181014122344
官方文檔中Bugly的常見(jiàn)問(wèn)題:https://bugly.qq.com/docs/user-guide/faq-android/?v=20181014122344