其实很简单 , tinker 的集成直接照着 官方 Demo 就行 , 这里我直接让 Tinker 去反射的 , 然后, 其实我们的问题出现在下发流程不清(官网解释不到位)
补丁生成失败: 看文章最下面
// 第一步 ,基础配置
0. 登陆官网,创建账号 , 创建 app
1. 下载官方的 Demo https://github.com/Tencent/tinker
2. 在 project 中的 build.gradle 中添加 Tinker 引用
3. 在 app 下的 build.gradle 中添加 Tinker 引用
4. build 一下项目(以上按开发文档进行就可以了)
5. 将 Demo 中 tinkerpatch.gradle 文件复制到自己的工程 , 目录结构搞一样的
6. 在 app 下的 build.gradle 中引入tinkerpatch.gradle 文件 ,就是这句话 apply from: 'tinkerpatch.gradle' 我放在了最下面
7. 新建自己的 Application , 按开发文档初始化 Tinker , 这里我直接让 Tinker 去反射
public class StoryBookApplication extends Application {
private static StoryBookApplication mInstance;
private ApplicationLike mTinkerApplicationLike;
public static StoryBookApplication getmInstance() {
return mInstance;
}
@Override
public void onCreate() {
super.onCreate();
initTinker();
mInstance = this;
}
/**
* 初始化热更新
*/
private void initTinker() {
// 我们可以从这里获得Tinker加载过程的信息
mTinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();
// 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化SDK
TinkerPatch.init(mTinkerApplicationLike)
.reflectPatchLibrary()
.setPatchRollbackOnScreenOff(true)
.setPatchRestartOnSrceenOff(true)
.setFetchPatchIntervalByHours(1);
// 每隔3个小时(通过setFetchPatchIntervalByHours设置)去访问后台时候有更新,通过handler实现轮训的效果
TinkerPatch.with().fetchPatchUpdateAndPollWithInterval();
// bugly
CrashReport.initCrashReport(getApplicationContext(), "1fddff9ddc", true);
TinkerPatch.with().fetchPatchUpdate(true); // 为 true, 每次强制访问服务器更新
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
}
}
8. 回到官网复制我们创建的 app 的 appKey
9. 修改 tinkerpatch.gradle 中的 appKey
10. 修改 app 下 build.gradle 中的 versionName 和 tinkerpatch.gradle 要一致 ,方便管理
11. 在 app 下 build.gradle 中的 defaultConfig 中添加如下代码 , 解决错误
defaultConfig {
applicationId rootProject.ext.app.applicationId
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.app.versionCode
versionName rootProject.ext.app.versionName
// 添加部分
multiDexEnabled true
javaCompileOptions { annotationProcessorOptions { includeCompileClasspath true } }
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
12. 再次 build 一下项目
13. 构建基准包 , 点击右侧 gradle 中 (root) 中的 assembleRelease 生成基准包 ,
这个包在左侧 app 目录下的 build 中的 bakApk 目录下
这个包一定要备份好 , 因为 clear 项目时会清掉这个文件夹 , 后面该版本的所有补丁都只能在这上面进行
如何备份: 直接复制文件夹放到 app 目录下
14. 关键一步: 我们需要将 tinkerpatch.gradle 文件中的基准包文件夹名 def baseInfo = "app-1.0.0-0723-20-27-34" 修改为我们第 13 步生成的文件夹名 , 后面打补丁会来找这里面的基准包的
补丁和基准包之间存在某种构建关系
15. 至此 , 第一个版本(可以上传到应用商店的包) 打好了
16. 一定要配置签名
// 第二步 ,发布补丁
1. 只要不是发布新版本(意思是希望修改app中的 versionName) , 只要 versionName 不用动 , tinkerpatch.gradle 中的配置就都不用改
2. 我们修改代码 , 加一句 Toast
3. 点击右侧 (root) 中的 Tinker 下面的 tinkerPatchRelease 生成补丁包
4. 回到官网中 , 找到你的 app , 新建版本(和当前的基准包中的 versionName 保持一致,方便管理)
5. 点击发布新补丁 , 找到你的项目下 app 模块中 build 下的 outputs 中的 apk 下的 tinkerPatch 中的 patch_signed.apk
6. 写个注释 , 点击全量发布
7. 重启2次你的 app ,看看结果
// 第三部 , 希望发布新版本
0. 修改我们 app 下 build.gradle 中的 versionName , 修改 tinkerpatch.gradle 中的 versionName 保持一致
1. 重新点击右上角的 gradle 中 root 下的 build 中的 assembleRelease ,生成新的基准包
2. 修改 基准包配置: def baseInfo = "app-1.0.0-0723-20-27-34" 修改为生成新的基准包的文件夹名
3. 这就是一个新的版本了 , 可以发布到线上
4. 到 Tinker 官网中找到我们的 app ,新建一个新版本 , 使之与我们现在的基准包版本保持一致
5. 又可以回到第二步中了, 继续根据当前的基准包打补丁发布了
3. 安装包加固: 使用的 360 加固
需要开启: tinkerpatch.gradle 中的
/** 是否开启加固模式,只有在使用加固时才能开启此开关 **/
protectedApp = true
参考网上提示:
首先生成基础包,然后使用 360 生成加固渠道包(上线市场的包),
若发现有问题,则用基础包作为 oldapk 生成 patch,给 360 加固渠道包打补丁,可以完成修复测试过了
开启加固模式和不开启加固模式区别(完美):https://juejin.im/post/5c175d27f265da614273ce1d
加固后,对新增 Activity 的支持处理: https://www.jianshu.com/p/05cf37ee971b
关于将我们备份的基准包,再次拿进到 build 中的 bakApk 中连接中断问题:
总结: 缓存也是一个很大的问题 , 可能会导致编译不成功 , 我一台机器上很好 , 一台机器上老是不成功 ,AndroidStudio 3.0.1
补丁生成失败:
较好的文章: 包含了很多解决方案: https://blog.csdn.net/bencheng06/article/details/90806434
总结:
1. 如果一 次 app 变动太大 , 建议直接更新版本,也就是修改 versionName 重新发布安装包 , 不然即使编译通过 , 补丁也打不上去 , app 会直接闪退
2. 也就是小修,小改用 Tinker 方便 , 大改的话还是老实的发包 , 另外我之前还运用过 360 的 Repugin , 也是恒不错的解决方案 , 且更新方式,我们能够更加主动
如果还有什么疑问,欢迎在评论区问我