demo地址: https://download.youkuaiyun.com/download/android410223sun/11869081(只看代码,可以粘贴复制就行,不能运行,因为你可登录不上我的Tinker账号哦 - - 。)
最近闲来无事,捉摸了下这个热修复东西,花了大概一天的时间写了个demo,然后测试上传热修复补丁,success!记录一下。
本人用的是微信开源的tinker,所以下面全是关于它的:
第一步:去tinker官网(http://www.tinkerpatch.com)注册个appkey 然后新建个项目 版本号跟应用名字最好跟你app内设置的一致。
patch版本:4 说明我已经上传了四个测试补丁。(如果你同时下发新旧好几个补丁,那么没用接收到旧补丁的设备就会直接安装最新的补丁)
现在已经有appkey跟版本号了。开始进入as:
在项目的根build.gradle的dependencies 中添加如下代码:
dependencies {
// TinkerPatch 插件
classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.1.8"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
在app的根build.gradle添加如下代码:
provided("com.tinkerpatch.tinker:tinker-android-anno:1.9.8")
compile("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.8")
还要在该文件的最下面同时加上 apply from: 'tinkerpatch.gradle'
tinkerpatch.gradle就是我们接下来要创建的tinker配置文件
它在这里新建:
《-----------------tinkerpatch.gradle全部代码 start------------------》
apply plugin: 'tinkerpatch-support'
/**
* TODO: 请按自己的需求修改为适应自己工程的参数
*/
//基包路径
def bakPath = file("${buildDir}/bakApk/")
//基包文件夹名(打补丁包的时候,需要修改)
def baseInfo = "app-1.0-1016-10-09-29" //第一次打基准包的时候 可以这样写def baseInfo = " "
////版本名称
def variantName = "debug"
/**
* 对于插件各参数的详细解析请参考
*
*/
tinkerpatchSupport {
//可以在debug的时候关闭 tinkerPatch
tinkerEnable = true
//是否使用一键接入功能 默认为false 是否反射 Application 实现一键接入;
// 一般来说,接入 Tinker 我们需要改造我们的 Application, 若这里为 true, 即我们无需对应用做任何改造即可接入。
reflectApplication = true
//将每次编译产生的 apk/mapping.txt/R.txt 归档存储的位置
autoBackupApkPath = "${bakPath}"
appKey = "f956d84445f9xxxx"// 注意!!!!!!!!! 需要修改成你的appkey appkey只跟线上的版本号(appVersion )有关系
/** 注意: 若发布新的全量包, appVersion一定要更新 **/
appVersion = "1.0" //这个对应的就是tinker平台上的版本 该版本的补丁只能给该版本提供线上热修复!
def pathPrefix = "${bakPath}/${baseInfo}/${variantName}/"
def name = "${project.name}-${variantName}"
/**
* 基准包的文件路径, 对应 tinker 插件中的 oldApk 参数;编译补丁包时,
* 必需指定基准版本的 apk,默认值为空,则表示不是进行补丁包的编译
*/
baseApkFile = "${pathPrefix}/${name}.apk"
/**
* 基准包的 Proguard mapping.txt 文件路径, 对应 tinker 插件 applyMapping 参数;在编译新的 apk 时候,
* 我们希望通过保持基准 apk 的 proguard 混淆方式,
* 从而减少补丁包的大小。这是强烈推荐的,编译补丁包时,我们推荐输入基准 apk 生成的 mapping.txt 文件。
*/
baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
/**
* 基准包的资源 R.txt 文件路径, 对应 tinker 插件 applyResourceMapping 参数;在编译新的apk时候,
* 我们希望通基准 apk 的 R.txt 文件来保持 Resource Id 的分配,这样不仅可以减少补丁包的大小,
* 同时也避免由于 Resource Id 改变导致 remote view 异常
*/
baseResourceRFile = "${pathPrefix}/${name}-R.txt"
/**
* 若有编译多flavors需求, 可以参照: https://github.com/TinkerPatch/tinkerpatch-flavors-sample
* 注意: 除非你不同的flavor代码是不一样的,不然建议采用zip comment或者文件方式生成渠道信息(相关工具:walle 或者 packer-ng)
**/
}
/**
* 用于用户在代码中判断tinkerPatch是否被使能
*/
android {
defaultConfig {
buildConfigField "boolean", "TINKER_ENABLE", "${tinkerpatchSupport.tinkerEnable}"
}
}
/**
* 一般来说,我们无需对下面的参数做任何的修改
* 对于各参数的详细介绍请参考:
* https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
*/
tinkerPatch {
ignoreWarning = false
useSign = true //是否需要签名,打正式包如果这里是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
}
}
《-----------------tinkerpatch.gradle全部代码 end------------------》
注:tinkerpatch.gradle这些代码你要注意的就是appVersion 跟 appKey 还有baseInfo 这三个参数 ,appVersion 跟appKey 前面已经说过了,baseInfo 的参数是打补丁包的时候需要用到的,后面会说,第一次打基准包的话就啥都不填。
开始初始化tinker:
public class MyAppApplication extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
// 我们可以从这里获得Tinker加载过程的信息
ApplicationLike tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();
// 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化SDK
TinkerPatch.init(tinkerApplicationLike)
.reflectPatchLibrary()
.setPatchRollbackOnScreenOff(true)
.setPatchRestartOnSrceenOff(true);
TinkerPatch.with().fetchPatchUpdate(true);// 实时访问后台时候有更新,通过handler实现轮训的效果
// 每隔3个小时去访问后台时候有更新,通过handler实现轮训的效果
// new FetchPatchHandler().fetchPatchWithInterval(1);
}
@Override
public void onTerminate() { // 程序终止的时候执行
super.onTerminate();
Log.e("kill","killed");
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
现在代码上就over了;
开始打基准包:(注:因为是测试 所以我下面打得都是debug的补丁跟基准包,发布线上的话就选择release的按钮)
然后bulid完成后在下面这里就会出现个apk文件:
这个apk文件就是你这次打出的基准包,现在你可以把它发送到到一台设备上进行安装,红圈圈起得那个文件夹名字(圈起来重点)打补丁要用到;
随便修改下你项目里的代码,布局,吐司之类的随便,就是为了方便看到补丁修上去了而已!
现在开始打补丁;修改tinkerpatch.gradle中的baseInfo 为上面红圈圈起来的名字,最好复制进去,比较长……
点击:
build完成后会生成
这个_7zip结尾的文件就是你这次打出的补丁。
然后把这个上传到我们刚开始在tinker平台中新建的项目中,点击发布补丁,大概5分钟左右吧,重启打开app,就会发现新修改的东西显示出来了。
就此结束。