| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> tinker热修复gradle接入,app软件开发课程 -> 正文阅读 |
|
[移动开发]tinker热修复gradle接入,app软件开发课程 |
keyAlias ‘china’ keyPassword ‘123456’ storeFile file(‘D:/work/release.jks’) storePassword ‘123456’ } catch (ex) { throw new InvalidUserDataException(ex.toString()) } } debug { storeFile file(‘D:/work/debug.jks’) keyAlias ‘china’ keyPassword ‘123456’ storePassword ‘123456’ } } defaultConfig { applicationId “tinker.sample.android” minSdkVersion 10 targetSdkVersion 22 versionCode 1 versionName “1.0.0” /**
*/ multiDexEnabled true /**
*/ buildConfigField “String”, “MESSAGE”, ““I am the base apk”” // buildConfigField “String”, “MESSAGE”, ““I am the patch apk”” /**
*/ buildConfigField “String”, “TINKER_ID”, "“1.0"” buildConfigField “String”, “PLATFORM”, ““all”” } // aaptOptions{ // cruncherEnabled false // } // //use to test flavors support // productFlavors { // flavor1 { // applicationId ‘tinker.sample.android.flavor1’ // } // // flavor2 { // applicationId ‘tinker.sample.android.flavor2’ // } // } buildTypes { release { minifyEnabled true signingConfig signingConfigs.release proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’ } debug { debuggable true minifyEnabled false signingConfig signingConfigs.debug proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’ } } sourceSets { main { jniLibs.srcDirs = [‘libs’] } } } def bakPath = file("${buildDir}/bakApk/") /**
*/ //老版本的文件所在的位置,大家也可以动态配置,不用每次都在这里修改 ext { //for some
reason, you may want to ignore tinkerBuild, such as instant run debug build? tinkerEnabled = true //for normal build //old apk file to build patch apk tinkerOldApkPath = “${bakPath}/app-release-0313-16-16-16.apk” //proguard mapping file to build patch apk tinkerApplyMappingPath = “${bakPath}/app-release-0313-16-16-mapping.txt” //resource R.txt to build patch apk, must input if there is resource changed tinkerApplyResourcePath = “${bakPath}/app-release-0313-16-16-R.txt” //only use for build all flavor, if not, just ignore this field tinkerBuildFlavorDirectory = “${bakPath}/app-1018-17-32-47” } def getOldApkPath() { return hasProperty(“OLD_APK”) ? OLD_APK : ext.tinkerOldApkPath } def getApplyMappingPath() { return hasProperty(“APPLY_MAPPING”) ? APPLY_MAPPING : ext.tinkerApplyMappingPath } def getApplyResourceMappingPath() { return hasProperty(“APPLY_RESOURCE”) ? APPLY_RESOURCE : ext.tinkerApplyResourcePath } //废弃 /*def getTinkerIdValue() { return hasProperty(“TINKER_ID”) ? TINKER_ID : gitSha() }*/ def buildWithTinker() { return hasProperty(“TINKER_ENABLE”) ? TINKER_ENABLE : ext.tinkerEnabled } def getTinkerBuildFlavorDirectory() { return ext.tinkerBuildFlavorDirectory } if (buildWithTinker()) { apply plugin: ‘com.tencent.tinker.patch’ tinkerPatch { /**
*/ oldApk = getOldApkPath() /**
*/ ignoreWarning = true /**
*/ useSign = true /**
*/ tinkerEnable = buildWithTinker() /**
*/ buildConfig { /**
*/ applyMapping = getApplyMappingPath() /**
*/ applyResourceMapping = getApplyResourceMappingPath() /**
*/ tinkerId = “1.0”/getTinkerIdValue()/ /**
*/ keepDexApply = false } dex { /**
*/ dexMode = “jar” /**
*/ pattern = [“classes*.dex”, “assets/secondary-dex-?.jar”] /**
*/ loader = [ //use sample, let BaseBuildInfo unchangeable with tinker “tinker.sample.android.app.BaseBuildInfo” ] } lib { /**
*/ pattern = [“lib//.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”) } //or you can add config filed outside, or get meta value from old apk //project.tinkerPatch.packageConfig.configField(“test1”, project.tinkerPatch.packageConfig.getMetaDataFromOldApk(“Test”)) //project.tinkerPatch.packageConfig.configField(“test2”, “sample”) /**
*/ sevenZip { /**
*/ zipArtifact = “com.tencent.mm:SevenZip:1.1.10” /**
*/ // path = “/usr/local/bin/7za” } } List flavors = new ArrayList<>(); project.android.productFlavors.each {flavor -> flavors.add(flavor.name) } boolean hasFlavors = flavors.size() > 0 /**
*/ android.applicationVariants.all { variant -> /**
*/ 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 = “ p r o j e c t . n a m e ? {project.name}- project.name?{variant.baseName}” def newFileNamePrefix = hasFlavors ? “ f i l e N a m e P r e f i x " : " {fileNamePrefix}" : " fileNamePrefix":"{fileNamePrefix}-${date}” def destPath = hasFlavors ? file(" b a k P a t h / {bakPath}/ bakPath/{project.name}- d a t e / {date}/ date/{variant.flavorName}") : bakPath from variant.outputs.outputFile into destPath rename { String fileName -> fileName.replace(" f i l e N a m e P r e f i x . a p k " , " {fileNamePrefix}.apk", " fileNamePrefix.apk","{newFileNamePrefix}.apk") } from “ b u i l d D i r / o u t p u t s / m a p p i n g / {buildDir}/outputs/mapping/ buildDir/outputs/mapping/{variant.dirName}/mapping.txt” into destPath rename { String fileName -> fileName.replace(“mapping.txt”, “${newFileNamePrefix}-mapping.txt”) } from “ b u i l d D i r / i n t e r m e d i a t e s / s y m b o l s / {buildDir}/intermediates/symbols/ buildDir/intermediates/symbols/{variant.dirName}/R.txt” into destPath rename { String fileName -> fileName.replace(“R.txt”, “${newFileNamePrefix}-R.txt”) } } } } } } project.afterEvaluate { //sample use for build all flavor for one time 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 = “ o r i g i n O l d P a t h / {originOldPath}/ originOldPath/{flavorName}/ p r o j e c t . n a m e ? {project.name}- project.name?{flavorName}-release.apk” project.tinkerPatch.buildConfig.applyMapping = “ o r i g i n O l d P a t h / {originOldPath}/ originOldPath/{flavorName}/ p r o j e c t . n a m e ? {project.name}- project.name?{flavorName}-release-mapping.txt” project.tinkerPatch.buildConfig.applyResourceMapping = “ o r i g i n O l d P a t h / {originOldPath}/ originOldPath/{flavorName}/ p r o j e c t . n a m e ? {project.name}- 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 = “ o r i g i n O l d P a t h / {originOldPath}/ originOldPath/{flavorName}/ p r o j e c t . n a m e ? {project.name}- project.name?{flavorName}-debug.apk” project.tinkerPatch.buildConfig.applyMapping = “ o r i g i n O l d P a t h / {originOldPath}/ originOldPath/{flavorName}/ p r o j e c t . n a m e ? {project.name}- project.name?{flavorName}-debug-mapping.txt” project.tinkerPatch.buildConfig.applyResourceMapping = “ o r i g i n O l d P a t h / {originOldPath}/ originOldPath/{flavorName}/ p r o j e c t . n a m e ? {project.name}- project.name?{flavorName}-debug-R.txt” } } } } } } 主要修改了下面几个地方 buildConfigField “String”, “TINKER_ID”, “”${getTinkerIdValue()}"" 官方文档默认是将git提交的记录作为think_id记录下来,这里我不需要,所以我改成下图 buildConfigField “String”, “TINKER_ID”, "“1.0"” 我直接写死,需要git提交记录作为tinker_id的也可以按照官方文档推荐的写 同时,这些地方也可以相应的替换掉 //废弃 /*def getTinkerIdValue() { return hasProperty(“TINKER_ID”) ? TINKER_ID : gitSha() }*/ tinkerId = “1.0”/getTinkerIdValue()/ 接下来修改自己的签名文件,我这里配置的文件路径是自己电脑上面的,这个位置大家需要修改为自己的签名文件路径,也可以按照我的去生成一个签名文件,我相信这个还是很简单的 //配置自己的签名文件,签名文件的生成和导入可以去百度,本篇不讲解 signingConfigs { release { try { keyAlias ‘china’ keyPassword ‘123456’ storeFile file(‘D:/work/release.jks’) storePassword ‘123456’ } catch (ex) { throw new InvalidUserDataException(ex.toString()) } } debug { storeFile file(‘D:/work/debug.jks’) keyAlias ‘china’ keyPassword ‘123456’ storePassword ‘123456’ } } buildTypes { release { minifyEnabled true signingConfig signingConfigs.release proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’ } debug { debuggable true minifyEnabled false signingConfig signingConfigs.debug proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’ } } 官网文档没有设置debug的 proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’也就是说没有应用混淆文件,这样是不会生成mapping文件的,所以这里我也加上 android.applicationVariants.all { variant -> /**
*/ 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 = “ p r o j e c t . n a m e ? {project.name}- project.name?{variant.baseName}” def newFileNamePrefix = hasFlavors ? “ f i l e N a m e P r e f i x " : " {fileNamePrefix}" : " fileNamePrefix":"{fileNamePrefix}-${date}” def destPath = hasFlavors ? file(" b a k P a t h / {bakPath}/ bakPath/{project.name}- d a t e / {date}/ date/{variant.flavorName}") : bakPath from variant.outputs.outputFile into destPath rename { String fileName -> fileName.replace(" f i l e N a m e P r e f i x . a p k " , " {fileNamePrefix}.apk", " fileNamePrefix.apk","{newFileNamePrefix}.apk") } from “ b u i l d D i r / o u t p u t s / m a p p i n g / {buildDir}/outputs/mapping/ buildDir/outputs/mapping/{variant.dirName}/mapping.txt” into destPath rename { String fileName -> fileName.replace(“mapping.txt”, “${newFileNamePrefix}-mapping.txt”) } from “ b u i l d D i r / i n t e r m e d i a t e s / s y m b o l s / {buildDir}/intermediates/symbols/ buildDir/intermediates/symbols/{variant.dirName}/R.txt” into destPath rename { String fileName -> fileName.replace(“R.txt”, “${newFileNamePrefix}-R.txt”) } } } } } 这下面主要是设置生成的文件所在的目录是什么 配置完上面之后,build就配置好了,接下来配置application 先上代码 package com.anlaiye.swt.gradletest; import android.app.Application; import android.content.Context; import android.content.Intent; import android.support.multidex.MultiDex; import com.tencent.tinker.anno.DefaultLifeCycle; import com.tencent.tinker.lib.tinker.TinkerInstaller; import com.tencent.tinker.loader.app.ApplicationLike; import com.tencent.tinker.loader.shareutil.ShareConstants; @DefaultLifeCycle(application = “.SimpleTinkerInApplication”, flags = ShareConstants.TINKER_ENABLE_ALL, loadVerifyFlag =true) public class SimpleTinkerInApplicationLike extends ApplicationLike { public SimpleTinkerInApplicationLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) { super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent); } @Override public void onBaseContextAttached(Context base) { super.onBaseContextAttached(base); MultiDex.install(base); TinkerInstaller.install(this); } @Override public void onCreate() { super.onCreate(); } } 这个application官网有提供的,也可以copy我的,ApplicationLike 并不是一个application 真正的application是@DefaultLifeCycle(application = “.SimpleTinkerInApplication”,这个 所以在androidmanifest中配置applica的name <application android:name=".SimpleTinkerInApplication" android:allowBackup=“true” android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl=“true” android:theme="@style/AppTheme"> |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 7:25:00- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |