<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                三、Tinker 的配置及任務 1、開啟支持大工程模式 Tinker 文檔中推薦將jumboMode 設置為true。 ``` android { dexOptions { // 支持大工程模式 jumboMode = true } ... } ``` 2、配置Tinker 與任務 將下面的配置全部復制粘貼到app 的gradle 文件(app/build.gradle)末尾,內容很多,但現在只需要看懂bakPath 與ext 括號內的東東就好了。 ``` // Tinker 配置與任務 def bakPath = file("${buildDir}/bakApk/") ext { // 是否使用Tinker(當你的項目處于開發調試階段時,可以改為false) tinkerEnabled = true // 基礎包文件路徑(名字這里寫死為old-app.apk。用于比較新舊app 以生成補丁包,不管是debug 還是release 編譯) tinkerOldApkPath = "${bakPath}/old-app.apk" // 基礎包的mapping.txt 文件路徑(用于輔助混淆補丁包的生成,一般在生成release 版app 時會 使用到混淆,所以這個mapping.txt 文件一般只是用于release 安裝包補丁的生成) tinkerApplyMappingPath = "${bakPath}/old-app-mapping.txt" // 基礎包的R.txt 文件路徑(如果你的安裝包中資源文件有改動,則需要使用該R.txt 文件來輔助生 成補丁包) tinkerApplyResourcePath = "${bakPath}/old-app-R.txt" //only use for build all flavor, if not, just ignore this field tinkerBuildFlavorDirectory = "${bakPath}/flavor" } 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 : android.defaultConfig.versionName } def buildWithTinker() { return hasProperty("TINKER_ENABLE") ? TINKER_ENABLE : ext.tinkerEnabled } def getTinkerBuildFlavorDirectory() { return ext.tinkerBuildFlavorDirectory } if (buildWithTinker()) { //apply tinker 插件 apply plugin: 'com.tencent.tinker.patch' // 全局信息相關的配置項 tinkerPatch { tinkerEnable = buildWithTinker()// 是否打開tinker 的功能。 oldApk = getOldApkPath() // 基準apk 包的路徑,必須輸入,否則會報錯。 ignoreWarning = false // 是否忽略有風險的補丁包。這里選擇不忽略,當補丁包風 險時會中斷編譯。 useSign = true // 在運行過程中,我們需要驗證基準apk 包與補丁包的簽名 是否一致,我們是否需要為你簽名。 // 編譯相關的配置項 buildConfig { applyMapping = getApplyMappingPath() // 可選參數;在編譯新的apk 時候,我們希望通過保持舊apk 的proguard 混淆方式,從 而減少補丁包的大小。這個只是推薦設置,不設置applyMapping 也不會影響任何的assemble 編譯。 applyResourceMapping = getApplyResourceMappingPath() // 可選參數;在編譯新的apk 時候,我們希望通過舊apk 的R.txt 文件保持ResId 的分配, 這樣不僅可以減少補丁包的大小,同時也避免由于ResId 改變導致remote view 異常。 tinkerId = getTinkerIdValue() // 在運行過程中,我們需要驗證基準apk 包的tinkerId 是否等于補丁包的tinkerId。這個 是決定補丁包能運行在哪些基準包上面,一般來說我們可以使用git 版本號、versionName 等等。 keepDexApply = false // 如果我們有多個dex,編譯補丁時可能會由于類的移動導致變更增多。若打開 keepDexApply 模式,補丁包將根據基準包的類分布來編譯。 isProtectedApp = false // 是否使用加固模式,僅僅將變更的類合成補丁。注意,這種模 式僅僅可以用于加固應用中。 supportHotplugComponent = false // 是否支持新增非export 的Activity(1.9.0 版本 開始才有的新功能) } // dex 相關的配置項 dex { dexMode = "jar" // 只能是'raw'或者'jar'。對于'raw'模式,我們將會保持輸入dex 的格式。對于'jar'模式,我們將會把 輸入dex 重新壓縮封裝到jar。如果你的minSdkVersion 小于14,你必須選擇‘jar’模式,而且它更省存 儲空間,但是驗證md5 時比'raw'模式耗時。默認我們并不會去校驗md5,一般情況下選擇jar 模式即可。 pattern = ["classes*.dex", "assets/secondary-dex-?.jar"] // 需要處理dex 路徑,支持*、?通配符,必須使用'/'分割。路徑是相對安裝包的,例如assets/... loader = [ // 定義哪些類在加載補丁包的時候會用到。這些類是通過Tinker 無法修改的類,也 是一定要放在main dex 的類。 // 如果你自定義了TinkerLoader,需要將它以及它引用的所有類也加入loader 中; // 其他一些你不希望被更改的類,例如Sample 中的BaseBuildInfo 類。這里需要 注意的是,這些類的直接引用類也需要加入到loader 中。或者你需要將這個類變成非preverify。 ] } // lib 相關的配置項 lib { pattern = ["lib/*/*.so","src/main/jniLibs/*/*.so"] // 需要處理lib 路徑,支持*、?通配符,必須使用'/'分割。與dex.pattern 一致, 路徑是相 對安裝包的,例如assets/... } // res 相關的配置項 res { pattern = ["res/*", "assets/*", "resources.arsc", "AndroidManifest.xml"] // 需要處理res 路徑,支持*、?通配符,必須使用'/'分割。與dex.pattern 一致, 路徑是相 對安裝包的,例如assets/...,務必注意的是,只有滿足pattern 的資源才會放到合成后的資源包。 ignoreChange = [ // 支持*、?通配符,必須使用'/'分割。若滿足ignoreChange 的pattern,在編譯 時會忽略該文件的新增、刪除與修改。最極端的情況,ignoreChange 與上面的pattern 一致,即會完 全忽略所有資源的修改。 "assets/sample_meta.txt" ] largeModSize = 100 // 對于修改的資源,如果大于largeModSize,我們將使用bsdiff 算法。這可以降低補丁包 的大小,但是會增加合成時的復雜度。默認大小為100kb } // 用于生成補丁包中的'package_meta.txt'文件 packageConfig { // configField("key", "value"), 默認我們自動從基準安裝包與新安裝包的Manifest 中讀取 tinkerId,并自動寫入configField。 // 在這里,你可以定義其他的信息,在運行時可以通過 TinkerLoadResult.getPackageConfigByName 得到相應的數值。 // 但是建議直接通過修改代碼來實現,例如BuildConfig。 configField("platform", "all") configField("patchVersion", "1.0") // configField("patchMessage", "tinker is sample to use") } // 7zip 路徑配置項,執行前提是useSign 為true 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 from variant.outputs.first().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 { //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" } } } } } } ``` 其中,有幾點配置在這里說明一下,方便理解后續的操作(當tinkerEnabled = true 的情況下): 1.app 的生成目錄是:主Module(一般是名為app)/build/bakApk 文件夾。 2.補丁包的生成路徑:主Module(一般是名為app)/build/outputs/apk/tinkerPatch/debug/patch_signed_7zip.apk。 3.基礎包的名字:old-app.apk,放于bakApk 文件夾下。 4.基礎包的mapping.txt 和R.txt 文件一般在編譯release 簽名的apk 時才會用到。 5.在用到mapping.txt 文件時,需要重命名為old-app-mapping.txt,放于bakApk 文件夾下。 6.在用到R.txt 文件時,需要重命名為old-app-R.txt,放于bakApk 文件夾下。 對于mapping.txt 和R.txt 文件,在配置中有說明,請回配置中仔細看。上面只是我項目中的配置,這些其實都是可以自定義的,建議在搞清楚配置內容之后再去自定義修改。 3、什么是基礎包?? 基礎包就是已經上架的apk 文件(假設是1.0 版本)。這其實很好理解,在新版 本的App 上架之前(假設是2.0 版本),我們會用到Tinker 來修復1.0 版App 中存在的bug,這時就需要用到Tinker 來產生補丁包文件,而補丁包文件的本 質,就是修復好Bug 的App 與1.0 版本App 之間的文件差異。在2.0 版本上架 之前,我們可能會多次產生新的補丁包,用于修復在用戶手機上的1.0 版App, 所以補丁包必須以1.0 版App 作為參考標準,也就是說用戶手機上的app 就是 基礎包,即當前應用市場上的apk 文件(前面說的1.0 版本)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看