java -jar tinker-patch-cli-1.7.7.jar -old old.apk -new new.apk -config tinker_config.xml -out output
|
配置在application节点下
<meta-data
|
android:name="TINKER_ID"
|
android:value="tinker_id_6235657"
|
/>
|
gradle.properties
TINKER_VERSION=1.9.1
|
classpath "com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}"
apply plugin: 'com.android.application'
|
def bakPath = file("${buildDir}/bakApk")
|
android {
|
signingConfigs {
|
release {
|
keyAlias 'key0'
|
keyPassword '121212'
|
storeFile file('C:/Project/fast2/MyApplication/app/n.jks')
|
storePassword '121212'
|
}
|
}
|
compileSdkVersion 26
|
defaultConfig {
|
applicationId "com.lee.cn.myapplication"
|
minSdkVersion 15
|
targetSdkVersion 26
|
versionCode 1
|
versionName "1.0"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
|
}
|
buildTypes {
|
release {
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
signingConfig signingConfigs.release
|
}
|
}
|
}
|
dependencies {
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation 'com.android.support:appcompat-v7:26.1.0'
|
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
|
testImplementation 'junit:junit:4.12'
|
androidTestImplementation 'com.android.support.test:runner:1.0.1'
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
|
compile 'com.alipay.euler:andfix:0.5.0@aar'
|
//optional, help to generate the final application
|
provided "com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}"
|
//tinker's main Android lib
|
compile "com.tencent.tinker:tinker-android-lib:${TINKER_VERSION}"
|
compile 'com.android.support:multidex:1.0.1'
|
}
|
ext {
|
tinkerEnable = true
|
tinkerOldApkPath = "${bakPath}/app-0511-12-36-20"
|
tinkerID = "1.0"
|
tinkerApplyMappingPath = "${bakPath}/
app-0511-12-36-20
"
|
tinkerApplyResourcePath = "${bakPath}/
app-0511-12-36-20
"
|
tinkerBuildFlavorDirectory = "${bakPath}/
app-0511-12-36-20
"
|
}
|
def buildWithTinker() {
|
return ext.tinkerEnable
|
}
|
def getOldApkPath() {
|
return ext.tinkerOldApkPath
|
}
|
def getApplyMappingPath() {
|
return ext.tinkerApplyMappingPath
|
}
|
def getApplyResourceMappingPath() {
|
return ext.tinkerApplyResourcePath
|
}
|
def getTinkerIdValue() {
|
return ext.tinkerID
|
}
|
def getTinkerBuildFlavorDirectory(){
|
return ext.tinkerBuildFlavorDirectory
|
}
|
if (buildWithTinker()) {
|
//启用tinker
|
apply plugin: 'com.tencent.tinker.patch'
|
//所有tinker相关的参数配置
|
tinkerPatch {
|
oldApk = getOldApkPath() //指定old apk文件径
|
ignoreWarning = false //不忽略tinker的警告,有则中止patch文件的生成
|
useSign = true //强制patch文件也使用签名
|
tinkerEnable = buildWithTinker(); //指定是否启用tinker
|
buildConfig {
|
applyMapping = getApplyMappingPath() //指定old apk打包时所使用的混淆文件
|
applyResourceMapping = getApplyResourceMappingPath() //指定old apk的资源文件
|
tinkerId = getTinkerIdValue() //指定TinkerID
|
keepDexApply = false
|
}
|
dex {
|
dexMode = "jar" //jar、raw
|
pattern = ["classes*.dex", "assets/secondary-dex-?.jar"] //指定dex文件目录
|
loader = ["
com.imooc.tinker.MyTinkerApplication
"] //指定加载patch文件时用到的类
|
}
|
lib {
|
pattern = ["libs/*/*.so"]
|
}
|
res {
|
pattern = ["res/*", "assets/*", "resources.arcs", "AndoridManifest.xml"]
|
//指定tinker可以修改的资源路径
|
ignoreChange = ["assets/sample_meta.txt"] //指定不受影响的资源路径
|
largeModSize = 100 //资源修改大小默认值
|
}
|
packageConfig {
|
configField("patchMessage", "fix the 1.0 version's bugs")
|
configField("patchVersion", "1.0")
|
}
|
}
|
List<String> flavors = new ArrayList<>();
|
project.android.productFlavors.each { flavor ->
|
flavors.add(flavor.name)
|
}
|
boolean hasFlavors = flavors.size() > 0
|
/**
|
* 复制基准包和其它必须文件到指定目录
|
*/
|
android.applicationVariants.all { variant ->
|
/**
|
* task type, you want to bak
|
*/
|
def taskName = variant.name
|
def date = new Date().format("MMdd-HH-mm-ss")
|
tasks.all {
|
if ("assemble${taskName.capitalize()}".equalsIgnoreCase(it.name)) {
|
it.doLast {
|
copy {
|
def fileNamePrefix = "${project.name}-${variant.baseName}"
|
def newFileNamePrefix = hasFlavors ? "${fileNamePrefix}" : "${fileNamePrefix}-${date}"
|
def destPath = hasFlavors ? file("${bakPath}/${project.name}-${date}/${variant.flavorName}") : bakPath
|
from variant.outputs.outputFile
|
into destPath
|
rename { String fileName ->
|
fileName.replace("${fileNamePrefix}.apk", "${newFileNamePrefix}.apk")
|
}
|
from "${buildDir}/outputs/mapping/${variant.dirName}/mapping.txt"
|
into destPath
|
rename { String fileName ->
|
fileName.replace("mapping.txt", "${newFileNamePrefix}-mapping.txt")
|
}
|
from "${buildDir}/intermediates/symbols/${variant.dirName}/R.txt"
|
into destPath
|
rename { String fileName ->
|
fileName.replace("R.txt", "${newFileNamePrefix}-R.txt")
|
}
|
}
|
}
|
}
|
}
|
}
|
project.afterEvaluate {
|
if (hasFlavors) {
|
task(tinkerPatchAllFlavorRelease) {
|
group = 'tinker'
|
def originOldPath = getTinkerBuildFlavorDirectory()
|
for (String flavor : flavors) {
|
def tinkerTask = tasks.getByName("tinkerPatch${flavor.capitalize()}Release")
|
dependsOn tinkerTask
|
def preAssembleTask = tasks.getByName("process${flavor.capitalize()}ReleaseManifest")
|
preAssembleTask.doFirst {
|
String flavorName = preAssembleTask.name.substring(7, 8).toLowerCase() + preAssembleTask.name.substring(8, preAssembleTask.name.length() - 15)
|
project.tinkerPatch.oldApk = "${originOldPath}/${flavorName}/${project.name}-${flavorName}-release.apk"
|
project.tinkerPatch.buildConfig.applyMapping = "${originOldPath}/${flavorName}/${project.name}-${flavorName}-release-mapping.txt"
|
project.tinkerPatch.buildConfig.applyResourceMapping = "${originOldPath}/${flavorName}/${project.name}-${flavorName}-release-R.txt"
|
}
|
}
|
}
|
task(tinkerPatchAllFlavorDebug) {
|
group = 'tinker'
|
def originOldPath = getTinkerBuildFlavorDirectory()
|
for (String flavor : flavors) {
|
def tinkerTask = tasks.getByName("tinkerPatch${flavor.capitalize()}Debug")
|
dependsOn tinkerTask
|
def preAssembleTask = tasks.getByName("process${flavor.capitalize()}DebugManifest")
|
preAssembleTask.doFirst {
|
String flavorName = preAssembleTask.name.substring(7, 8).toLowerCase() + preAssembleTask.name.substring(8, preAssembleTask.name.length() - 13)
|
project.tinkerPatch.oldApk = "${originOldPath}/${flavorName}/${project.name}-${flavorName}-debug.apk"
|
project.tinkerPatch.buildConfig.applyMapping = "${originOldPath}/${flavorName}/${project.name}-${flavorName}-debug-mapping.txt"
|
project.tinkerPatch.buildConfig.applyResourceMapping = "${originOldPath}/${flavorName}/${project.name}-${flavorName}-debug-R.txt"
|
}
|
}
|
}
|
}
|
}
|
}
|