1
1
# SDK 接入
2
2
3
- [ ![ Download] ( https://api.bintray.com/packages/simsun/maven/tinkerpatch-android-sdk/images/download.svg ) ] ( https://bintray.com/simsun/maven/tinkerpatch-android-sdk/_latestVersion )
3
+ [ ![ Build Status] ( https://travis-ci.org/TinkerPatch/tinkerpatch-sample.svg?branch=master )] ( https://travis-ci.org/TinkerPatch/tinkerpatch-sample )
4
+ [ ![ Download] ( https://api.bintray.com/packages/simsun/maven/tinkerpatch-android-sdk/images/download.svg ) ] ( https://bintray.com/simsun/maven/tinkerpatch-android-sdk/_latestVersion )
5
+ [ ![ Join Slack] ( https://slack.tinkerpatch.com/badge.svg )] ( https://slack.tinkerpatch.com )
4
6
5
7
这里只是针对 TinkerPatch SDK的使用说明,对于 Tinker 的基本用法,可参考[ Tinker 接入指南] ( https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97 ) 。 Tinker SDK 在 Github 为大家提供了大量的范例,大家可点击前往 [[ TinkerPatch Samples]] ( https://github.com/TinkerPatch ) .
6
8
7
9
## 第一步 添加 gradle 插件依赖
8
10
9
- gradle 远程仓库依赖 jcenter, 例如 TinkerPatch Sample 中的[ build.gradle] ( https://github.com/TinkerPatch/tinkerpatch-sample/blob/master/build.gradle ) .
11
+ gradle 远程仓库依赖 jcenter, 例如 TinkerPatch Sample 中的 [ build.gradle] ( https://github.com/TinkerPatch/tinkerpatch-sample/blob/master/build.gradle ) .
10
12
11
13
```
12
14
buildscript {
@@ -15,25 +17,25 @@ buildscript {
15
17
}
16
18
dependencies {
17
19
// TinkerPatch 插件
18
- classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.1.4 "
20
+ classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.1.6 "
19
21
}
20
22
}
21
23
```
22
24
23
- ** 注意,在这里SDK使用了fat打包的模式 ,我们不能再引入任何 Tinker 的相关依赖,否则会造成版本冲突。当前SDK是基于 tinker 1.7.7 内核开发的。**
25
+ ** 注意,在这里 SDK 使用了 fat 打包的模式 ,我们不能再引入任何 Tinker 的相关依赖,否则会造成版本冲突。当前 SDK 是基于 tinker 1.7.9 内核开发的。**
24
26
25
27
## 第二步 集成 TinkerPatch SDK
26
28
27
- 添加TinkerPatch SDK 库的 denpendencies 依赖, 可参考 Sample 中的 [ app/build.gradle] ( https://github.com/TinkerPatch/tinkerpatch-sample/blob/master/app/build.gradle ) :
29
+ 添加 TinkerPatch SDK 库的 denpendencies 依赖, 可参考 Sample 中的 [ app/build.gradle] ( https://github.com/TinkerPatch/tinkerpatch-sample/blob/master/app/build.gradle ) :
28
30
29
31
```
30
32
dependencies {
31
33
// 若使用annotation需要单独引用,对于tinker的其他库都无需再引用
32
- provided("com.tencent.tinker:tinker-android-anno:1.7.7 ")
33
- compile("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.1.4 ")
34
+ provided("com.tencent.tinker:tinker-android-anno:1.7.9 ")
35
+ compile("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.1.6 ")
34
36
}
35
37
```
36
- ** 注意,若使用 annotation 自动生成 Application, 需要单独引入 Tinker的 tinker-android-anno 库。除此之外,我们无需再单独引入 tinker 的其他库。**
38
+ ** 注意,若使用 annotation 自动生成 Application, 需要单独引入 Tinker 的 tinker-android-anno 库。除此之外,我们无需再单独引入 tinker 的其他库。**
37
39
38
40
为了简单方便,我们将 TinkerPatch 相关的配置都放于 [ tinkerpatch.gradle] ( https://github.com/TinkerPatch/tinkerpatch-sample/blob/master/app/tinkerpatch.gradle ) 中, 我们需要将其引入:
39
41
@@ -42,53 +44,48 @@ apply from: 'tinkerpatch.gradle'
42
44
```
43
45
44
46
## 第三步 配置 tinkerpatchSupport 参数
45
- 打开引入的 tinkerpatch.gradle 文件,它的具体参数如下:
47
+ 打开引入的 [ tinkerpatch.gradle] ( https://github.com/TinkerPatch/tinkerpatch-sample/blob/master/app/tinkerpatch.gradle ) 文件,它的具体参数如下:
46
48
47
49
```
48
50
tinkerpatchSupport {
51
+ tinkerpatchSupport {
49
52
/** 可以在debug的时候关闭 tinkerPatch **/
50
53
tinkerEnable = true
54
+
55
+ /** 是否使用一键接入功能 **/
51
56
reflectApplication = true
52
- appKey = "${yourAppKey}"
57
+
53
58
autoBackupApkPath = "${bakPath}"
54
59
55
- baseApkInfos {
56
- item {
57
- variantName = "debug"
58
- appVersion = "1.0.0"
59
- baseApkFile = "${pathPrefix}/${name}.apk"
60
- baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
61
- baseResourceRFile = "${pathPrefix}/${name}-R.txt"
62
- }
63
- item {
64
- variantName = "release"
65
- appVersion = "1.0.0"
66
- baseApkFile = "${pathPrefix}/${name}.apk"
67
- baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
68
- baseResourceRFile = "${pathPrefix}/${name}-R.txt"
69
- }
70
- }
60
+ /** 在tinkerpatch.com得到的appKey **/
61
+ appKey = "yourAppKey"
62
+ /** 注意: 若发布新的全量包, appVersion一定要更新 **/
63
+ appVersion = "1.0.0"
64
+
65
+ def pathPrefix = "${bakPath}/${baseInfo}/${variantName}/"
66
+ def name = "${project.name}-${variantName}"
67
+
68
+ baseApkFile = "${pathPrefix}/${name}.apk"
69
+ baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
70
+ baseResourceRFile = "${pathPrefix}/${name}-R.txt"
71
71
}
72
72
```
73
73
74
- ** 这里缺失了部分变量的声明,完整例子可以参照上文中给的链接**
75
-
76
74
它的具体含义如下:
77
75
78
76
| 参数 | 默认值 | 描述 |
79
77
| ----------------- | --------- | --------- |
80
78
| tinkerEnable | true | 是否开启 tinkerpatchSupport 插件功能。 |
81
79
| appKey | "" | 在 TinkerPatch 平台 申请的 appkey, 例如 sample 中的 'f828475486f91936' |
82
80
| appVersion | "" | 在 TinkerPatch 平台 输入的版本号, 例如 sample 中的 '1.0.0'。 ** 注意,我们使用 appVersion 作为 TinkerId, 我们需要保证每个发布出去的基础安装包的 appVersion 都不一样。** |
83
- | ` reflectApplication ` | false | 是否反射 Application 实现一键接入;** 一般来说,接入 Tinker 我们需要改造我们的 Application, 若这里为 true, 即我们无需对应用做任何改造即可接入** 。|
81
+ | reflectApplication | false | 是否反射 Application 实现一键接入;** 一般来说,接入 Tinker 我们需要改造我们的 Application, 若这里为 true, 即我们无需对应用做任何改造即可接入** 。|
84
82
| autoBackupApkPath | "" | 将每次编译产生的 apk/mapping.txt/R.txt 归档存储的位置|
85
83
| baseApkFile | "" | ` 基准包的文件路径, 对应 tinker 插件中的 oldApk 参数 ` ;编译补丁包时,必需指定基准版本的 apk,默认值为空,则表示不是进行补丁包的编译。 |
86
84
| baseProguardMappingFile | "" | ` 基准包的 Proguard mapping.txt 文件路径, 对应 tinker 插件 applyMapping 参数 ` ;在编译新的 apk 时候,我们希望通过保持基准 apk 的 proguard 混淆方式,从而减少补丁包的大小。这是强烈推荐的,编译补丁包时,我们推荐输入基准 apk 生成的 mapping.txt 文件。 |
87
85
| baseResourceRFile | "" | ` 基准包的资源 R.txt 文件路径, 对应 tinker 插件 applyResourceMapping 参数 ` ;在编译新的apk时候,我们希望通基准 apk 的 R.txt 文件来保持 Resource Id 的分配,这样不仅可以减少补丁包的大小,同时也避免由于 Resource Id 改变导致 remote view 异常。 |
86
+ | protectedApp | false | 是否开启支持加固,** 注意:只有在使用加固时才能开启此开关** |
88
87
89
88
90
- ** 我们可以平行的在` baseApkInfos ` 中定义多组item,用来达到适配不同的flavor编译。**
91
-
92
89
** 一般来说,我们无需修改引用 android 的编译配置,也不用修改 tinker 插件原来的配置** 。针对特殊需求,具体的参数含义可参考 Tinker 文档:[ Tinker 接入指南] ( https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97 ) .
93
90
94
91
## 第四步 初始化 TinkerPatch SDK
@@ -109,13 +106,14 @@ public class SampleApplication extends Application {
109
106
tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();
110
107
111
108
// 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化SDK
112
- TinkerPatch.init(tinkerApplicationLike )
109
+ TinkerPatch.init(this )
113
110
.reflectPatchLibrary()
114
111
.setPatchRollbackOnScreenOff(true)
115
- .setPatchRestartOnSrceenOff(true);
112
+ .setPatchRestartOnSrceenOff(true)
113
+ .setFetchPatchIntervalByHours(3);
116
114
117
- // 每隔3个小时去访问后台时候有更新 ,通过handler实现轮训的效果
118
- new FetchPatchHandler ().fetchPatchWithInterval(3 );
115
+ // 每隔3个小时(通过setFetchPatchIntervalByHours设置)去访问后台时候有更新 ,通过handler实现轮训的效果
116
+ TinkerPatch.with ().fetchPatchUpdateAndPollWithInterval( );
119
117
}
120
118
121
119
...
@@ -139,22 +137,132 @@ public class SampleApplicationLike extends DefaultApplicationLike {
139
137
TinkerPatch.init(this)
140
138
.reflectPatchLibrary()
141
139
.setPatchRollbackOnScreenOff(true)
142
- .setPatchRestartOnSrceenOff(true);
140
+ .setPatchRestartOnSrceenOff(true)
141
+ .setFetchPatchIntervalByHours(3);
143
142
144
- // 每隔3个小时去访问后台时候有更新 ,通过handler实现轮训的效果
145
- new FetchPatchHandler ().fetchPatchWithInterval(3 );
143
+ // 每隔3个小时(通过setFetchPatchIntervalByHours设置)去访问后台时候有更新 ,通过handler实现轮训的效果
144
+ TinkerPatch.with ().fetchPatchUpdateAndPollWithInterval( );
146
145
}
147
146
148
147
...
149
148
150
149
}
151
150
```
152
151
152
+ ** 注意:初始化的代码建议紧跟 super.onCreate(),并且所有进程都需要初始化,已达到所有进程都可以被 patch 的目的**
153
+
154
+ ** 如果你确定只想在主进程中初始化 tinkerPatch,那也请至少在 : patch 进程中初始化,否则会有造成 : patch 进程crash,无法使补丁生效**
155
+
153
156
## 第五步 使用步骤
154
157
TinkerPatch 的使用步骤非常简单,一般来说可以参考以下几个步骤:
155
158
156
- 1 . 运行 ` assembleRelease ` task 构建基准包,即将要发布的版本;
157
- 2 . 通过 ` autoBackupApkPath ` 保存编译的产物 apk/mapping.txt/R.txt 文件;
158
- 3 . 若想发布补丁包, 只需将步骤2保存下来的文件分别填到 ` baseApkFile ` /` baseProguardMappingFile ` /` baseResourceRFile ` 参数中;
159
- 4 . 运行 ` tinkerPatchRelease ` task 构建补丁包,补丁包将位于 ` build/outputs/tinkerPatch ` 中;
160
- 5 . 1.1.0版本开始TinkerPatch支持了多Flavor多AppVersion的配置,可以按自己的需求添加相应item即可。
159
+ 1 . 运行 ` assembleRelease ` task 构建基准包(** 请在发布前确保更新tinkerpatchSupport中的appVersion** ),tinkerPatch会基于你填入的` autoBackupApkPath ` 自动备份基础包信息到相应的文件夹,包含:apk文件、R.txt文件和mapping.txt文件
160
+ (** 注:mapping.txt是proguard的产物,如果你没有开启proguard则不会有这个文件** )
161
+ 2 . 若想发布补丁包, 只需将自动保存下来的文件分别填到` tinkerpatchSupport ` 中的` baseApkFile ` 、` baseProguardMappingFile ` 和` baseResourceRFile ` 参数中;
162
+ 3 . 运行 ` tinkerPatchRelease ` task 构建补丁包,补丁包将位于 ` build/outputs/tinkerPatch ` 下。
163
+
164
+ ## 其他
165
+
166
+ ### 1. 对Flavors的支持
167
+
168
+ 在TinkerPatchSupport中添加如下字段, 如果你只是多渠道的需求,建议不要使用Flavor。多flavor必须在后台建立相应的基线工程(如下例子的命名规则为:appVersion_flavorName),每次生成补丁时也必须对应的生成多个分别上传。
169
+
170
+ 这里增加了` tinkerPatchAllFlavorsDebug ` 和 ` tinkerPatchAllFlavorsRelease ` 用于一次性生成所有flavors的Patch包。
171
+
172
+ 具体可以参照[ tinkerpatch-flavors-sample] ( https://github.com/TinkerPatch/tinkerpatch-flavors-sample ) 。
173
+
174
+ ** 如果只是多渠道的需求,建议不要使用flavor的方式。首先其打包很慢,其次需要维护多个基线包,后期维护成本也很大。Tinker官方推荐 [ packer-ng-plugin] ( https://github.com/mcxiaoke/packer-ng-plugin ) 或者 [ walle] ( https://github.com/Meituan-Dianping/walle ) 来进行多渠道打包,其中walle是支持最新的SchemaV2签名的。**
175
+
176
+ ```
177
+ /** 若有编译多flavors需求,可在flavors中覆盖以下参数
178
+ * 你也可以直接通过tinkerPatchAllFlavorDebug/tinkerPatchAllFlavorRelease, 一次编译所有的flavor补丁包
179
+ * 注意的是:除非你不同的flavor代码是不一样的,不然建议采用zip comment或者文件方式生成渠道信息
180
+ **/
181
+ productFlavors {
182
+ flavor {
183
+ flavorName = "flavor1"
184
+ // 后台需要按照每个flavor的appVersion来建立独立的工程,并单独下发补丁
185
+ appVersion = "${tinkerpatchSupport.appVersion}_${flavorName}"
186
+
187
+ pathPrefix = "${bakPath}/${baseInfo}/${flavorName}${buildType}/"
188
+ name = "${project.name}-${flavorName}${buildType}"
189
+
190
+ baseApkFile = "${pathPrefix}/${name}.apk"
191
+ baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
192
+ baseResourceRFile = "${pathPrefix}/${name}-R.txt"
193
+ }
194
+
195
+ flavor {
196
+ flavorName = "flavor2"
197
+ // 后台需要按照每个flavor的appVersion来建立独立的工程,并单独下发补丁
198
+ appVersion = "${tinkerpatchSupport.appVersion}_${flavorName}"
199
+
200
+ pathPrefix = "${bakPath}/${baseInfo}/${flavorName}${buildType}/"
201
+ name = "${project.name}-${flavorName}${buildType}"
202
+
203
+ baseApkFile = "${pathPrefix}/${name}.apk"
204
+ baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
205
+ baseResourceRFile = "${pathPrefix}/${name}-R.txt"
206
+ }
207
+ }
208
+ ```
209
+
210
+ ### 2. 对加固的支持
211
+
212
+ 这里默认大家有同时生成加固渠道与非加固渠道的需求,如果只是单一需要加固,可以直接在配置中开启` protectedApp = true ` 即可。
213
+
214
+ 可以参考tinkerpatch.gradle文件,具体工程可以参照[ tinkerpatch-flavors-sample] ( https://github.com/TinkerPatch/tinkerpatch-flavors-sample ) :
215
+ ```
216
+ productFlavors {
217
+ flavor {
218
+ flavorName = "protect"
219
+ appVersion = "${tinkerpatchSupport.appVersion}_${flavorName}"
220
+
221
+ pathPrefix = "${bakPath}/${baseInfo}/${flavorName}-${variantName}/"
222
+ name = "${project.name}-${flavorName}-${variantName}"
223
+
224
+ baseApkFile = "${pathPrefix}/${name}.apk"
225
+ baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
226
+ baseResourceRFile = "${pathPrefix}/${name}-R.txt"
227
+
228
+ /** 开启加固开关,上传此flavor的apk到加固网站进行加固 **/
229
+ protectedApp = true
230
+ }
231
+
232
+ flavor {
233
+ flavorName = "flavor1"
234
+ appVersion = "${tinkerpatchSupport.appVersion}_${flavorName}"
235
+
236
+ pathPrefix = "${bakPath}/${baseInfo}/${flavorName}-${variantName}/"
237
+ name = "${project.name}-${flavorName}-${variantName}"
238
+
239
+ baseApkFile = "${pathPrefix}/${name}.apk"
240
+ baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
241
+ baseResourceRFile = "${pathPrefix}/${name}-R.txt"
242
+ }
243
+ }
244
+ ```
245
+
246
+ #### 加固步骤:
247
+
248
+ 1 . 生成开启` protectedApp = true ` 的基础包(这里假设此APK名为:` protected.apk ` );
249
+ 2 . 上传` protected.apk ` 到相应的加固网站进行加固,并发布应用市场(请遵循各个加固网站步骤,一般为下载加固包-》重新签名-》发布重签名加固包);
250
+ 3 . 在tinkerPatch后台根据appVersion建立相应的App版本(比如这里2个flavor,就需要建立2个App版本。App版本即为各自flavor中配置的appVersion);
251
+ 4 . 基于各个flavor的基础包(** 这里的基础包是第一步中生成的未加固的版本** )生成相应patch包,并上传至相应的App版本中,即完成补丁发布。
252
+
253
+ ** protectedApp=true, 这种模式仅仅可以使用在加固应用中**
254
+
255
+ #### 支持列表:
256
+
257
+ | 加固厂商 | 测试 |
258
+ | --------| --------- |
259
+ | 乐加固 | Tested |
260
+ | 爱加密 | Tested |
261
+ | 梆梆加固 | Tested |
262
+ | 360加固 | TODO(对特定场景的Android N支持还存在问题)|
263
+ | 其他 | 请自行测试,只要满足下面规则的都可以支持 |
264
+
265
+ 这里是否支持加固,需要加固厂商明确以下两点:
266
+
267
+ 1 . 不能提前导入类;
268
+ 2 . 在art平台若要编译oat文件,需要将内联取消。
0 commit comments