haohao

分分钟接入Tinker

Tinker是什么

Tinker是微信官方的Android热补丁解决方案,它支持动态下发代码、So库以及资源,让应用能够在不需要重新安装的情况下实现更新。当然,你也可以使用Tinker来更新你的插件。
它主要包括以下几个部分:

  • 1.gradle编译插件: tinker-patch-gradle-plugin

  • 2.核心sdk库: tinker-android-lib

  • 3.非gradle编译用户的命令行版本: tinker-patch-cli.jar



Tinker

引入依赖和插件

在你项目根目录下的 build.gradle 文件中添加:

1
2
3
4
5
buildscript {
dependencies {
classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.7.6')
}
}

app/build.gradle 文件中添加依赖和插件:

1
2
3
4
5
6
7
8
9
10
11
dependencies {
//optional, help to generate the final application
provided('com.tencent.tinker:tinker-android-anno:1.7.6')
//tinker's main Android lib
compile('com.tencent.tinker:tinker-android-lib:1.7.6')
compile "com.android.support:multidex:1.0.1"
}
...
...
apply plugin: 'com.tencent.tinker.patch'

添加task

添加task tinkerPatchapp/build.gradle 文件中,其中 oldApk 路径为出现BUG的APK路径(自定义),添加完之后Async Project。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
tinkerPatch {
oldApk = "J://tinkerSample/app-debug.apk"
ignoreWarning = true
useSign = true
buildConfig {
applyMapping = null
applyResourceMapping = null
tinkerId = "tinkerId"
}
dex {
dexMode = "jar"
usePreGeneratedPatchDex = false
pattern = ["classes*.dex",
"assets/secondary-dex-?.jar"]
loader = ["com.tencent.tinker.loader.*",
"com.jc.tinkersample.SimpleApp",
"com.jc.tinkersample.BaseBuildInfo"
]
}
lib {
pattern = ["lib/armeabi/*.so"]
}
res {
pattern = ["res/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]
ignoreChange = ["assets/sample_meta.txt"]
largeModSize = 100
}
packageConfig {
configField("patchMessage", "tinker is sample to use")
configField("platform", "all")
configField("patchVersion", "1.0")
}
sevenZip {
zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
}
}

接入Tinker

自定义Application继承 DefaultApplicationLike 类,也可以自定义扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@DefaultLifeCycle(
application = "com.jc.tinkersample.SimpleApp",
flags = ShareConstants.TINKER_ENABLE_ALL,
loadVerifyFlag = false
)
public class SimpleAppLike extends DefaultApplicationLike {
public SimpleAppLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent, Resources[] resources, ClassLoader[] classLoader, AssetManager[] assetManager) {
super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent, resources, classLoader, assetManager);
}
@Override
public void onBaseContextAttached(Context base) {
super.onBaseContextAttached(base);
MultiDex.install(base);
TinkerInstaller.install(this);
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback) {
getApplication().registerActivityLifecycleCallbacks(callback);
}
}

运行安装到你的手机里,然后把 app-debug.apk 放到 oldApk 对应的路径下,用于生成 patch.apk

app_debug

然后,修复你项目的bug(这里只是象征性地修改了一下Text),打开Android Studio 右侧的gradle project 运行 tinkerPatchDebug task生成patch.apk

command

tinker_task

找到patch_signed_7zip.apk 文件。

new_apk

复制 patch_signed_7zip.apk 文件把它放到手机外部存储目录下 (这里为根目录)。

1
2
3
4
5
6
7
8
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk";
File file = new File(path);
if (file.exists()){
Toast.makeText(this, "patch.apk is existing.", Toast.LENGTH_SHORT).show();
TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), path);
}else{
Toast.makeText(this,"patch.apk is inexistent.", Toast.LENGTH_SHORT).show();
}

调用Tinker API TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), path); 进行热修复,重启app热修复完成。

详细代码https://github.com/githubhaohao/TinkerSample

更多

  1. 微信Android热补丁实践演进之路
  2. Android N混合编译与对热补丁影响深度解析
  3. 微信Tinker的一切都在这里,包括源码


联系我

Wechat ID

公众号

生活不止于眼前的苟且, 还有诗和远方的田野