本文已经授权微信公众号:鸿洋(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