本文记录,集成Bugly Tinker 步骤,以及遇到的问题。
Bugly官网文档
步骤1:添加依赖
1,项目目录下的build.gradle
添加 classpath 'com.tencent.bugly:tinker-support:1.1.5'
。如下图:
项目下的build.gradle.png
2,在app目录下的
build.gradle
添加如下配置
- 添加
// 依赖插件脚本
apply from: 'tinker-support.gradle'
- dependencies中添加
// 多dex配置
implementation "com.android.support:multidex:1.0.2"
//以下为热更新
implementation 'com.tencent.bugly:crashreport_upgrade:1.3.5'
// 指定tinker依赖版本(注:应用升级1.3.5版本起,不再内置tinker)
implementation 'com.tencent.tinker:tinker-android-lib:1.9.6'
implementation 'com.tencent.bugly:nativecrashreport:latest.release'
附上整个app下的build.gradle
图片:
app下的build.gradle.png
步骤2:配置自己的Application
下面可以直接拷贝使用,只需要将 appid 替换为自己申请的。
注:记得在AndroidManifest.xml
中声明替换为自己的application
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
setStrictMode();
// 设置是否开启热更新能力,默认为true
Beta.enableHotfix = true;
// 设置是否自动下载补丁
Beta.canAutoDownloadPatch = true;
// 设置是否提示用户重启
Beta.canNotifyUserRestart = true;
// 设置是否自动合成补丁
Beta.canAutoPatch = true;
/**
* 全量升级状态回调
*/
Beta.upgradeStateListener = new UpgradeStateListener() {
@Override
public void onUpgradeFailed(boolean b) {
}
@Override
public void onUpgradeSuccess(boolean b) {
}
@Override
public void onUpgradeNoVersion(boolean b) {
Toast.makeText(getApplicationContext(), "最新版本", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrading(boolean b) {
Toast.makeText(getApplicationContext(), "onUpgrading", Toast.LENGTH_SHORT).show();
}
@Override
public void onDownloadCompleted(boolean b) {
}
};
/**
* 补丁回调接口,可以监听补丁接收、下载、合成的回调
*/
Beta.betaPatchListener = new BetaPatchListener() {
@Override
public void onPatchReceived(String patchFileUrl) {
Toast.makeText(getApplicationContext(), patchFileUrl, Toast.LENGTH_SHORT).show();
}
@Override
public void onDownloadReceived(long savedLength, long totalLength) {
Toast.makeText(getApplicationContext(), String.format(Locale.getDefault(),
"%s %d%%",
Beta.strNotificationDownloading,
(int) (totalLength == 0 ? 0 : savedLength * 100 / totalLength)), Toast.LENGTH_SHORT).show();
}
@Override
public void onDownloadSuccess(String patchFilePath) {
Toast.makeText(getApplicationContext(), patchFilePath, Toast.LENGTH_SHORT).show();
// Beta.applyDownloadedPatch();
}
@Override
public void onDownloadFailure(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
@Override
public void onApplySuccess(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
@Override
public void onApplyFailure(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
@Override
public void onPatchRollback() {
Toast.makeText(getApplicationContext(), "onPatchRollback", Toast.LENGTH_SHORT).show();
}
};
long start = System.currentTimeMillis();
// Bugly.setUserId(this, "falue");
// Bugly.setUserTag(this, 123456);
// Bugly.putUserData(this, "key1", "123");
// Bugly.setAppChannel(this, "bugly");
// 这里实现SDK初始化,appId替换成你的在Bugly平台申请的appId,调试时将第三个参数设置为true
Bugly.init(this, "0b5cd33f13", true);
long end = System.currentTimeMillis();
Log.e("init time--->", end - start + "ms");
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// you must install multiDex whatever tinker is installed!
MultiDex.install(base);
// 安装tinker
Beta.installTinker();
}
@TargetApi(9)
protected void setStrictMode() {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
}
}
步骤3:在项目目录结构下创建 tinker-support.gradle
tinker-support.gradle.png
tinker-support.gradle
中内容如下(有可以去官网查看具体的),全部代码如下:
apply plugin: 'com.tencent.bugly.tinker-support'
def bakPath = file("${buildDir}/bakApk/")
/**
* 此处填写每次构建生成的基准包目录
*/
def baseApkDir = "app-1115-15-59-47"
/**
* 对于插件各参数的详细解析请参考
*/
tinkerSupport {
// 开启tinker-support插件,默认值true
enable = true
// 自动生成tinkerId, 你无须关注tinkerId,默认为false
autoGenerateTinkerId = true
// 指定归档目录,默认值当前module的子目录tinker
autoBackupApkDir = "${bakPath}"
// 是否启用覆盖tinkerPatch配置功能,默认值false
// 开启后tinkerPatch配置不生效,即无需添加tinkerPatch
overrideTinkerPatchConfiguration = true
// 编译补丁包时,必需指定基线版本的apk,默认值为空
// 如果为空,则表示不是进行补丁包的编译
// @{link tinkerPatch.oldApk }
baseApk = "${bakPath}/${baseApkDir}/app-release.apk"
// baseApk = "${bakPath}/${baseApkDir}/app-debug.apk"
// 对应tinker插件applyMapping
baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-release-mapping.txt"
// baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-debug-mapping.txt"
// 对应tinker插件applyResourceMapping
baseApkResourceMapping = "${bakPath}/${baseApkDir}/app-release-R.txt"
// baseApkResourceMapping = "${bakPath}/${baseApkDir}/app-debug-R.txt"
// 构建基准包跟补丁包都要修改tinkerId,主要用于区分
// tinkerId = "1.0.3-ccc"
// 打多渠道补丁时指定目录
// buildAllFlavorsDir = "${bakPath}/${baseApkDir}"
// 是否使用加固模式,默认为false
// isProtectedApp = true
// 是否采用反射Application的方式集成,无须改造Application
enableProxyApplication = true
// 支持新增Activity
supportHotplugComponent = true
}
/**
* 一般来说,我们无需对下面的参数做任何的修改
* 对于各参数的详细介绍请参考:
* https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
*/
tinkerPatch {
tinkerEnable = true
ignoreWarning = false
useSign = false
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 = "base-2.0.1"
}
}
步骤4:生成基准包(俗称有bug的线上包)
- 基准包生成步骤,点击项目右侧的gradle,如下图
image.png
等待完成之后,会在改目录下生成一个app-release.apk
文件,并将tinker-support.gradle
的baseApkDir
修改为跟生成的文件一致(例如下图的app-1115-15-59-47
)。
基准包生成.png
步骤5:生成差分包(热修复包,已经修复bug的包)
注意,需要使用下图的gradle生成,否则会有问题:
差分包.png
生成完成,左侧该目录下会出现一个
patch_signed_7zip.apk
(注意是patch下生成)patch_signed_7zip.apk.png
注意:差分包,生成需要使用的是tinker-support目录下的buildTinkerPatchRelease
步骤6:将生成的差分包上传到Bugly控制台
上传差分包.png
推送完成后,应用会重启(使用者下次打开),就可以看到你热修复的部分了。
注:需要存储权限,如果不成功,请检查一下权限是否打开!