美文网首页
tinker 的使用

tinker 的使用

作者: 客观开发者 | 来源:发表于2022-03-08 10:26 被阅读0次

    引入 gradel

    buildscript {
        repositories {
            google()
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.5.3'
            classpath("com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}") {
                changing = TINKER_VERSION?.endsWith("-SNAPSHOT")
                exclude group: 'com.android.tools.build', module: 'gradle'
            }
        }
        configurations.all {
            it.resolutionStrategy.cacheDynamicVersionsFor(5, 'minutes')
            it.resolutionStrategy.cacheChangingModulesFor(0, 'seconds')
        }
    }
    
    allprojects {
        repositories {
            google()
            jcenter()
        }
    }
    
    
    

    引入最新的

    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        testImplementation 'junit:junit:4.12'
        implementation "androidx.appcompat:appcompat:1.1.0"
        api("com.tencent.tinker:tinker-android-lib:${TINKER_VERSION}") { changing = true }
    
        // Maven local cannot handle transist dependencies.
        implementation("com.tencent.tinker:tinker-android-loader:${TINKER_VERSION}") { changing = true }
    
        annotationProcessor("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true }
        compileOnly("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}") { changing = true }
        compileOnly("com.tencent.tinker:tinker-android-anno-support:${TINKER_VERSION}") { changing = true }
    
        implementation "androidx.multidex:multidex:2.0.1"
    
    }
    
    def getTinkerIdValue() {
        return "1.0.0"
    }
    
    
    image.png

    目前最新版本
    TINKER_VERSION=1.9.14.19

    单独引用这个文件


    image.png

    代码如下

    
    def bakPath = file("${buildDir}/bakApk/")
    
    /**
     * you can use assembleRelease to build you base apk
     * use tinkerPatchRelease -POLD_APK=  -PAPPLY_MAPPING=  -PAPPLY_RESOURCE= to build patch
     * add apk from the build/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-0307-15-58-58.apk"
        //proguard mapping file to build patch apk
        tinkerApplyMappingPath = "${bakPath}/app-release-0307-15-58-58-mapping.txt"
        //resource R.txt to build patch apk, must input if there is resource changed
        tinkerApplyResourcePath = "${bakPath}/app-release-0307-15-58-58-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 buildWithTinker() {
        return hasProperty("TINKER_ENABLE") ? Boolean.parseBoolean(TINKER_ENABLE) : ext.tinkerEnabled
    }
    
    def getTinkerBuildFlavorDirectory() {
        return ext.tinkerBuildFlavorDirectory
    }
    
    if (buildWithTinker()) {
        apply plugin: 'com.tencent.tinker.patch'
    
        tinkerPatch {
    
            oldApk = getOldApkPath()
            ignoreWarning = false
            useSign = true
            tinkerEnable = buildWithTinker()
    
            buildConfig {
                applyMapping = getApplyMappingPath()
                applyResourceMapping = getApplyResourceMappingPath()
                tinkerId = getTinkerIdValue()
                keepDexApply = false
                isProtectedApp = false
                supportHotplugComponent = false
            }
    
            dex {
                dexMode = "jar"
                pattern = ["classes*.dex",
                           "assets/secondary-dex-?.jar"]
                loader = [
                        "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")
            }
    
            sevenZip {
                zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
            }
        }
    
        List<String> flavors = new ArrayList<>();
        project.android.productFlavors.each { flavor ->
            flavors.add(flavor.name)
        }
        boolean hasFlavors = flavors.size() > 0
        def date = new Date().format("MMdd-HH-mm-ss")
    
        /**
         * bak apk and mapping
         */
        android.applicationVariants.all { variant ->
            /**
             * task type, you want to bak
             */
            def taskName = variant.name
    
            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
    
                            if (variant.metaClass.hasProperty(variant, 'packageApplicationProvider')) {
                                def packageAndroidArtifact = variant.packageApplicationProvider.get()
                                if (packageAndroidArtifact != null) {
                                    try {
                                        from new File(packageAndroidArtifact.outputDirectory.getAsFile().get(), variant.outputs.first().apkData.outputFileName)
                                    } catch (Exception e) {
                                        from new File(packageAndroidArtifact.outputDirectory, variant.outputs.first().apkData.outputFileName)
                                    }
                                } else {
                                    from variant.outputs.first().mainOutputFile.outputFile
                                }
                            } else {
                                from variant.outputs.first().outputFile
                            }
    
                            into destPath
                            rename { String fileName ->
                                fileName.replace("${fileNamePrefix}.apk", "${newFileNamePrefix}.apk")
                            }
    
                            def dirName = variant.dirName
                            if (hasFlavors) {
                                dirName = taskName
                            }
                            from "${buildDir}/outputs/mapping/${dirName}/mapping.txt"
                            into destPath
                            rename { String fileName ->
                                fileName.replace("mapping.txt", "${newFileNamePrefix}-mapping.txt")
                            }
    
                            from "${buildDir}/intermediates/symbols/${dirName}/R.txt"
                            from "${buildDir}/intermediates/symbol_list/${dirName}/R.txt"
                            from "${buildDir}/intermediates/runtime_symbol_list/${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 = "${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"
                        }
    
                    }
                }
            }
        }
    }
    
    task sortPublicTxt() {
        doLast {
            File originalFile = project.file("public.txt")
            File sortedFile = project.file("public_sort.txt")
            List<String> sortedLines = new ArrayList<>()
            originalFile.eachLine {
                sortedLines.add(it)
            }
            Collections.sort(sortedLines)
            sortedFile.delete()
            sortedLines.each {
                sortedFile.append("${it}\n")
            }
        }
    }
    

    步骤如下:

    编译然后产生


    image.png

    将bakApk 文件复制出来


    image.png

    如这样,然后在进行


    image.png

    在编译一下,将 bbakApk删除,然后在 导入之前的复制出来的那个。


    image.png

    修改
    对于的名字


    image.png

    然后在进行


    image.png

    编译一下打包了。。。

    image.png

    app-release-patch_signed_7zip.apk 这个就是一个 升级包。。

    使用代码


    image.png

    重新启动app ,就算修复完成了。。。
    就此搞定。。。这个目前是最新版本。
    build:gradle 的版本。
    classpath 'com.android.tools.build:gradle:3.5.3'

    distributionUrl=https://services.gradle.org/distributions/gradle-6.1.1-all.zip

    感谢

    https://blog.csdn.net/qq_15527709/article/details/61921447

    相关文章

      网友评论

          本文标题:tinker 的使用

          本文链接:https://www.haomeiwen.com/subject/oxtarrtx.html