先說下我遇到的一些問題:
tinker1.9.0開始支持修改清單文件诗箍,可新增activity(exported = false)應(yīng)用內(nèi)部訪問的activity楷掉;暫不支持補丁更改應(yīng)用圖標;
release版本包混淆后叁征, 當(dāng)打7zip補丁包的時候全闷,可能會報出一些三方漂问,如地圖api的一些警告蔼水;
舉個栗子:
修改app proguard-rules.pro文件震糖,增加如下忽略,解決趴腋;
# 導(dǎo)航
-dontwarn? com.amap.**
配置:
1.相關(guān)配置:
【1】project build.gradle:(gradle3.0.0需要配置google())
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
// tinker-support 1.0.9 對應(yīng) tinker 1.9.0
// tinker-support 1.1.1 對應(yīng) tinker 1.9.1
classpath "com.tencent.bugly:tinker-support:1.1.1"
}
【2】
app gradle :
// 遠程倉庫集成方式(推薦) 熱修復(fù)
compile 'com.tencent.bugly:crashreport_upgrade:1.3.4'
//類似分包機制解決方案吊说,64k解決方案
compile 'com.android.support:multidex:1.0.1'
// 依賴插件腳本
apply from: 'tinker-support.gradle'
若項目中引入dagger2或者butterknife等三方插件,需要apt工具編譯优炬,需要修改相關(guān)配置颁井;
//gradle3.0.0的構(gòu)建方式
annotationProcessor 'com.google.dagger:dagger-compiler:2.6'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.2.1'
簽名配置:
signingConfigs {
release {
keyAlias '******'
keyPassword '***'
storePassword '*********'
storeFile file('D:/keystore/logistics.jks')
}
}
代碼混淆:release版本的包,必須混淆蠢护;否則編譯無法生成mapping文件
minifyEnabled true
【3】Manifest清單文件 雅宾, 若provider 里有用到,那么葵硕,直接增加到自己的provider中眉抬;
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
res下的xml文件夾下的file_paths.xml中加入:
<external-pathpath=""name="download"/>
<external-pathname="beta_external_path"path="Download/"/>
<external-pathname="beta_external_files_path"path="Android/data/" />
若沒有,則直接復(fù)制以下
android:name="com.tencent.bugly.beta.ui.BetaActivity"
android:configChanges="keyboardHidden|orientation|screenSize|locale"
android:theme="@android:style/Theme.Translucent"/>
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
【4】app module 創(chuàng)建 tinker-support.gradle 文件
apply plugin: 'com.tencent.bugly.tinker-support'
def bakPath = file("${buildDir}/bakApk/")
/**
*此處填寫每次構(gòu)建生成的基準包目錄贬芥,用戶安裝的版本吐辙,用于對比生成差分包的目錄宣决;
*/
def baseApkDir = "app-1220-11-39-55"
/**
* 對于插件各參數(shù)的詳細解析請參考
*/
tinkerSupport {
// 開啟tinker-support插件蘸劈,默認值true
enable = true
// 指定歸檔目錄,默認值當(dāng)前module的子目錄tinker
autoBackupApkDir = "${bakPath}"
// 是否啟用覆蓋tinkerPatch配置功能尊沸,默認值false
// 開啟后tinkerPatch配置不生效威沫,即無需添加tinkerPatch
overrideTinkerPatchConfiguration = true
// 編譯補丁包時,必需指定基線版本的apk洼专,默認值為空
// 如果為空棒掠,則表示不是進行補丁包的編譯
// @{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"
// 構(gòu)建基準包和補丁包都要指定不同的tinkerId,并且必須保證唯一性
tinkerId = "patch-1.3.0"
// 構(gòu)建多渠道補丁時使用
// buildAllFlavorsDir = "${bakPath}/${baseApkDir}"
// 是否啟用加固模式屁商,默認為false.(tinker-spport 1.0.7起支持)
// isProtectedApp = true
// 是否開啟反射Application模式 烟很, 這種模式不需要更改application結(jié)構(gòu),但是兼容性不高;
enableProxyApplication = true
// 是否支持新增非export的Activity(注意:設(shè)置為true才能修改AndroidManifest文件)
supportHotplugComponent = true
}
/**
* 一般來說,我們無需對下面的參數(shù)做任何的修改
* 對于各參數(shù)的詳細介紹請參考:
* 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文件芹橡,通過舊apk文件保持ResId的分配
}
}
【5】application--反射形式配置:
平臺注冊appid 毒坛;
@Override
public void onCreate() {
super.onCreate ();
//bugly熱修復(fù) ? ? ? ? ? ? ? ? ? ?//若設(shè)置稱true,只要手機連接電腦林说,就會在logcat中打印相關(guān)操作日志煎殷,日志Crash過濾;
Bugly.init (this, BUGLY_APPID, false);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext (base);
MultiDex.install (this);
// 安裝tinker
Beta.installTinker ();
//===========以下配置建議添加,親測若不添加腿箩,vivo手機補丁不生效豪直;
// 設(shè)置是否開啟熱更新能力,默認為true
Beta.enableHotfix = true;
// 設(shè)置是否自動下載補丁珠移,默認為true
Beta.canAutoDownloadPatch = true;
// 設(shè)置是否自動合成補丁顶伞,默認為true
Beta.canAutoPatch = true;
// 設(shè)置是否提示用戶重啟,默認為false
Beta.canNotifyUserRestart = false;
// 補丁回調(diào)接口
Beta.betaPatchListener = new BetaPatchListener () {
@Override
public void onPatchReceived(String patchFile) {
//? ? ? ? ? ? ? ? Toast.makeText (getApplication (), "補丁下載地址" + 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 (), "補丁下載成功", Toast.LENGTH_SHORT).show ();
}
@Override
public void onDownloadFailure(String msg) {
//? ? ? ? ? ? ? ? Toast.makeText (getApplication (), "補丁下載失敗" + msg, Toast.LENGTH_SHORT).show ();
}
@Override
public void onApplySuccess(String msg) {
//? ? ? ? ? ? ? ? Toast.makeText (getApplication (), "補丁應(yīng)用成功" + msg, Toast.LENGTH_SHORT).show ();
}
@Override
public void onApplyFailure(String msg) {
Toast.makeText (getApplication (), "補丁應(yīng)用失敗" + "========" + msg, Toast.LENGTH_SHORT).show ();
}
@Override
public void onPatchRollback() {
}
};
}
============================配置完成===========================請開始你的表演===================================
1.生成基準包剑梳,用戶安裝的基準包唆貌,需要本地將這個bakApk包保存,用于線上出現(xiàn)bug垢乙,對比生成補丁包锨咙;
雙擊后,會在app下生成bakApk的文件夾追逮;
這個app-release包酪刀,用于用戶安裝使用;(必須保證聯(lián)網(wǎng)使用了钮孵,否則上傳補丁包的時候骂倘,網(wǎng)頁會報,未匹配到使用app的用戶信息)
查看apk中巴席,發(fā)現(xiàn)目前我們的tinkerId版本是1.3.0历涝;
2.修改相應(yīng)bug,然后生成我們的補丁包漾唉;
【1】修改tinker-support荧库。gradle中的相關(guān)信息;
【2】增加tinkerId的版本號赵刑;
// 構(gòu)建基準包和補丁包都要指定不同的tinkerId分衫,并且必須保證唯一性,建議使用VersionCode或者VersionName作為名稱般此;
tinkerId = "patch-1.4.0"
【3】修復(fù)相應(yīng)bug
【4】生成補丁包蚪战;
雙擊:
outputs中生成patch文件夾牵现;
這個7Zip.apk就是生成的補丁包;
查看里面的.MF文件邀桑,這里可以看到我們的TinkerId從1.3版本施籍,更新到了1.4版本;
【5】開始上傳補丁啦概漱; ?選擇全量設(shè)備丑慎;也可以自定義,設(shè)定升級的android版本范圍瓤摧;4x 5x以上等竿裂; ? 開發(fā)設(shè)備用于開發(fā)者自己測試使用;后面會講到照弥;
下發(fā)完成后腻异,會等待下次進入應(yīng)用的時候,修復(fù)相應(yīng)bug这揣;但是需要1-10分鐘的時間悔常;
下發(fā)的補丁也可以撤回,撤回后相當(dāng)于未安裝該補丁给赞;
==============================================完成=========================================================
最后說下多渠道打包:
多渠道打包的時候机打,tinker-support.gradle中必須加上這個;
// 構(gòu)建多渠道補丁時使用
buildAllFlavorsDir = "${bakPath}/${baseApkDir}"
打補丁包的時候片迅,選擇生成全部的差分包
挨個發(fā)布多個補丁包即可残邀;