上一篇文章说道tinker的热更新,可是少了点补丁包的管理,这一篇文章介绍的bugly就是增强版的,更加方便你集成tinker和包括了补丁包的后台管理。
为什么使用 Bugly 热更新?
- 无需关注 Tinker 是如何合成补丁的
- 无需自己搭建补丁管理后台
- 无需考虑后台下发补丁策略的任何事情
- 无需考虑补丁下载合成的时机,处理后台下发的策略
- 我们提供了更加方便集成 Tinker 的方式
- 我们通过 HTTPS 及签名校验等机制保障补丁下发的安全性
- 丰富的下发维度控制,有效控制补丁影响范围
- 我们提供了应用升级一站式解决方案
Bugly下面我们用1.3.4版本的bugly来开发。
1.申请appid
去官网Bugly官网 申请appid比如asd778asd89,如果你之前应用bugly的异常上报就不用再申请appid。用的是同一个appid。
2.添加bugly插件
在项目的root目录下的build.gradle
classpath "com.tencent.bugly:tinker-support:1.1.1"
在app/build.gralde
android{
...
defaultConfig{
//开启dex分包
multiDexEnabled true
}
dexOption{
//大项目模式
jumboMode true
maxProcessCount 4
javaMaxHeapSize "2g"
}
//配置好签名
signingConfigs {
release {
keyAlias 'xx'
keyPassword 'xx'
storeFile file('../app/xxx.jks')
storePassword 'x'
v1SigningEnabled true
v2SigningEnabled true
}
}
//使用你的签名
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
}
dependiences{
implementation 'com.tencent.bugly:crashreport_upgrade:1.3.4'
implementation 'com.android.support:multidex:1.0.2'
}
如果你的项目之前使用了bugly的crash包就要去掉,因为crashreport_upgrade包里面包含了crash。不然会提示program is already.
3. 创建tinker-support.gradle文件
目标地址app/tinker-support.gradle,然后在app/build.gradle申请加入apply from: 'tinker-support.gradle'
这样子完成了70%。
//请求插件
apply plugin: 'com.tencent.bugly.tinker-support'
//基准包路径
def bakPath=file("${buildDir}/bakApk/")
//基准包父目录
def baseApkDir="app-0224-14-03-02"
//基准包的tinkerid
//def myTinkerId="base-"+"1.0"
//补丁包的tinkerid,每发布一个补丁包依次叠加一次补丁版本号(比如0.0->0.1)
def myTinkerId="patch-"+"1.0"+".0.1"
tinkerSupport{
//是否启动热修复,开发阶段设置为false
enable=true
//app要不要加固
isProtectedApp =false
//反射获取application
enableProxyApplication=false
//支持新增activity吗
supportHotplugComponent=true
autoBackupApkDir="${bakPath}"
//autoGenerateTinkerId = true
overrideTinkerPatchConfiguration =true
baseApk="${bakPath}/${baseApkDir}/app-release.apk"
// 对应tinker插件applyMapping
baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-release-mapping.txt"
// 对应tinker插件applyResourceMapping
baseApkResourceMapping = "${bakPath}/${baseApkDir}/app-release-R.txt"
tinkerId="${myTinkerId}"
}
/**
* 一般来说,我们无需对下面的参数做任何的修改
* 对于各参数的详细介绍请参考:
* 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" // 可选,设置mapping文件,建议保持旧apk的proguard混淆方式
//applyResourceMapping = "${bakPath}/${appName}/app-release-R.txt" // 可选,设置R.txt文件,通过旧apk文件保持ResId的分配
}
}
4. 创建ApplicationLike类
把项目的application继承为TinkerApplciation 在构造函数调用父类方法比如,最后在Androidmanifest。xml的application标签的name还是DemoApplication(继承TinkerApplication的Applciation)
里面有四个参数分别是
- 你要修复什么内容有dex so res等,全选就是TINKER_ENABLE_ALL
- ApplicationLike代理Application类,正真的oncreate attachBaseContext写在里面
- tinker的类加载器,默认是它
- 要不要验证md5 ,因为上文知道jar模式验证md5很慢,所以不验证了。
public class DemoApplication extends TinkerApplication {
public DemoApplication() {
super(ShareConstants.TINKER_ENABLE_ALL,
"com.ppjun.android.tinkerinbugly.DemoApplicationLike"
,"com.tencent.tinker.loader.TinkerLoader",false);
}
}
public class DemoApplicationLike extends DefaultApplicationLike {
public DemoApplicationLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) {
super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
}
@Override
public void onCreate() {
super.onCreate();
Beta.betaPatchListener=new BetaPatchListener() {
@Override
public void onPatchReceived(String s) {
}
@Override
public void onDownloadReceived(long l, long l1) {
}
@Override
public void onDownloadSuccess(String s) {
}
@Override
public void onDownloadFailure(String s) {
}
@Override
public void onApplySuccess(String s) {
}
@Override
public void onApplyFailure(String s) {
}
@Override
public void onPatchRollback() {
}
};
Bugly.setIsDevelopmentDevice(getApplication(),true);
Bugly.init(getApplication(),"6f399f3eeb",false);
//把你之前onCreate的逻辑写到这里
}
@Override
public void onBaseContextAttached(Context base) {
super.onBaseContextAttached(base);
MultiDex.install(base);
Beta.installTinker(this);
//把你之前applciation的attachbasecontext逻辑写到这里
}
public void registerActivityLifecycleCallback(Application.ActivityLifecycleCallbacks callbacks){
getApplication().registerActivityLifecycleCallbacks(callbacks);
}
@Override
public void onTerminate() {
super.onTerminate();
Beta.unInit();
}
}
- 确保在onBaseContextAttached里面分包和安装tinker
- 添加registerActivityLifecycleCallback方法和onTerminate方法
- 在oncreate注册你的appid
现在离完成还有10%。
剩下的就是打包了。
5. 打基准包
在tinker-support.gradle修改为基准包的tinkerId。
然后执行./gradlew assembleRelease
然后在app/build/bakApk看到一个app-0224-14-03-02 已打包时间为名字的文件夹,里面包含了有基准包app-release.apk,基准包的R.txt 和mapping.txt。
然后你可以安装基准包。
6.修改基准包
- 比如修改android.text="not patch" 改为android.text="has patch"
- 然后修改tinker-support.gradle的baseApkDir 。改为你刚才打基准包的父文件夹名字。比如
def baseApkDir="app-0224-14-03-02"
- 修改补丁包的tinkerId,每打一个补丁包补丁版本+1,补丁包的tinkerid=patch+apk版本号+补丁版本号
- 执行./gradlew buildTinkerPatchRelease,要和之前的打的release包对应。
- 在app/build/outputs/patch/得到补丁包patch_signed_7zip.apk。(**不要用outputs/apk/release/patch_signed_7zip.apk **)
7. 上传补丁包
上传补丁包后,目标版本会出现versionName+"."+versionCode 代表识别成功
如果上传补丁包后,没得到目标版本号,就是代表基准包还没被安装。或者安装后没联网。
或者基准包没安装tinker,没成功初始化tinker。
如果出现-1 -2这些错误码可以到TinkerLoadResult类看到对应的原因
全文完 ) ) >