本文已經授權微信公衆號:鴻洋(hongyangAndroid)原創首發
轉載請註明作者AndroidMsky和原文鏈接
http://blog.csdn.net/AndroidMsky/article/details/54135465
熱更新效果:
如今熱更新越來越火,各大廠也陸續開源自己的熱更新框架,先哪幾個看一眼優缺點:
個人覺得Tinker的第一個優勢就是支持類替換,lib替換,資源替換,也就是說,如果在高成功率的支持下,可以理解爲這套東西用於功能升級沒有壓力。
第二個優勢就是輕量,補丁包小,升級速度快性能高。Tinker採用算法產生差異包打補丁的方法,升級的補丁包確實非常小。
用於項目中想搞一些小功能的升級和bug的在線修復,在加上tinker比較完善的文檔,和飛鞋Tinker在刀塔中的帶線能力(瞎扯),我們決定集成Tinker使用。
https://github.com/Tencent/tinker/wiki
一切故事從文檔做起。當然這份文檔寫的很好,但是如果你對gradle對安卓項目結構理解還不那麼深入的話,集成起來還是有壓力的。於是我決定把我集成的過程和大家分享。就拿一個非常普通的項目例子開刀了,
http://blog.csdn.net/androidmsky/article/details/53607333
就是我之前介紹SwipeRefreshLayout的項目,好吧開始集成,我是參照tinker.sample.android官方提供的demo集成的,好吧走起。
1.現在項目的gradle文件中的dependencies中加入兩行(目前最新版本是1.7.6據說馬上要更新):
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
classpath "com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}"
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
2.因爲引入Tinker的版本變量所以在gradle.properties中加入
TINKER_VERSION=1.7.6
3.在修改app Module 的gradle文件這裏稍微複雜一點,我的做法是先把自己的gradle內容全部考出,然後將demo中的內容全部考入,然後修改對應位置內容,也可以一點一點的往裏面粘貼但是裏面有很多方法和字段,操作起來比較複雜(不推薦)。按我做的方法需要修改的幾個地方。在dependencies中配置你自己的依賴。
a.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile "com.android.support:appcompat-v7:23.1.1"
compile("com.tencent.tinker:tinker-android-lib:${TINKER_VERSION}") { changing = true }
provided("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true }
compile "com.android.support:multidex:1.0.1"
}
b.更改自己的安卓相應版本和一些其他信息
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.example.liangmutian.mskyswiperefreshlayout"
minSdkVersion 10
targetSdkVersion 22
versionCode 1
versionName "1.0.0"
c.配置自己的簽名(我就用了demo的簽名)
signingConfigs {
release {
try {
storeFile file("./keystore/release.keystore")
storePassword "testres"
keyAlias "testres"
keyPassword "testres"
} catch (ex) {
throw new InvalidUserDataException(ex.toString())
}
}
debug {
storeFile file("./keystore/debug.keystore")
}
}
差不多就這樣,這個gradle文件也就修改好了。
4.考入這幾個包和類和都是相關API調用的類:
然後修改一下包名爲自己的包名引用。
5.修改SampleApplicationLike上方的註釋:
@DefaultLifeCycle(application = "com.example.liangmutian.mskyswiperefreshlayout.AMSKY",
flags = ShareConstants.TINKER_ENABLE_ALL,
loadVerifyFlag = false)
這個註釋的大概意思就是自己在指定包下生成一個AMSKY的Application類,因爲tinker不希望我們自己創建Application並做修改,所以這樣用避免了對Application的修改,詳細見wiki中對自定義application的說明。
6.修改AndroidManifest.xml.也是一開始筆者遺漏的一個地方,此處懲罰自己今天晚上不打刀塔了,
補丁包要讀sd卡的所以:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
改爲剛剛5中自動生成的application
<application
android:name=".AMSKY"
註冊一個處理加載補丁結果的的service
<service
android:name=".service.SampleResultService"
android:exported="false"/>
7.在自己的activity中加入相關api引用,並在鎖屏後自動重啓進程:
public void load(View v) {
TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), "/sdcard/zhibo8/p.apk");
//
}
public void show(View v) {
showInfo(MainActivity.this);
}
public void clean(View v) {
Tinker.with(getApplicationContext()).cleanPatch();
}
public void kill(View v) {
ShareTinkerInternals.killAllOtherProcess(getApplicationContext());
android.os.Process.killProcess(android.os.Process.myPid());
}
@Override
protected void onResume() {
Log.e(TAG, "i am on onResume");
super.onResume();
Utils.setBackground(false);
}
@Override
protected void onPause() {
Log.e(TAG, "i am on onPause");
super.onPause();
Utils.setBackground(true);
}
這7步就在成功配置好了項目中的一些東西,好現在跑起命令驗證集成情況:
1.cd 到項目中,然後打個debug包:
2.打包成功在相應文件夾下回產生apk包和一個資源文件id的txt。如果是生產包還會有個混淆的mapping文件,(爲了看起來方便我把原有gradle代碼文件名縮短了一下)
3.把old apk和相應的東西填寫到app 的gradle文件中名字對應好:
ext {
//for some reason, you may want to ignore tinkerBuild, such as instant run debug build?
tinkerEnabled = true
//for normal build
//old apk file to build patch apk
tinkerOldApkPath = "${bakPath}/app-debug-41-01.apk"
//proguard mapping file to build patch apk
tinkerApplyMappingPath = "${bakPath}/app-debug-29-33-mapping.txt"
//resource R.txt to build patch apk, must input if there is resource changed
tinkerApplyResourcePath = "${bakPath}/app-debug-41-01-R.txt"
//only use for build all flavor, if not, just ignore this field
tinkerBuildFlavorDirectory = "${bakPath}/app-1018-17-32-47"
}
4.打一個差異包:
5.就會在相應文件夾下生成我們需要的差異包(我改了一行xml的代碼只生成了不到4k的差異包):
6.把差異包push到sd卡中大概是這樣的根據自己的路徑自己修改一下:
adb push /Users/wuduogen838/Desktop/Tinker/tinker-master/tinker-sample-android/app/build/outputs/tinkerPatch/debug/patch_signed_7zip.apk /sdcard/zhibo8 patch_signed_7zip.apk
7.安裝old apk開始測試(我僅僅是修改了一個xml中的button text)
點擊load並鎖屏:
我們看到button就這樣Tinker的集成和測就成功了。
我的例子也上傳到了Github上:
https://github.com/AndroidMsky/TinkerUseMSky
總結:
在tinker文檔的指導下,我也成功集成了tinker,熱更新框架的集成要比其他框架的集成複雜一點,需要具有一定的gradle知識,和項目結構知識,還要熟悉使用一些常用的gradle和adb命令,這次自己花了一天的時間集成tinker感覺能力又有一些提升,中間也踩了一些坑,特意拿出來跟大家分享。
阿里的AndFix集成初體驗來這裏傳送哈~
http://blog.csdn.net/androidmsky/article/details/54377806
歡迎關注作者。歡迎評論討論。歡迎拍磚。 如果覺得這篇文章對你有幫助,歡迎打賞, 歡迎star,Fork我的github。 喜歡作者的也可以Follow。也算對作者的一種支持。
歡迎加作者自營安卓開發交流羣:
308372687