Skip to content

Tinker Access Guide

shwenzhang edited this page Nov 9, 2017 · 30 revisions

Tinker Access Guide

Gradle access

Gradle is the recommended access method tinker-patch-gradle-plugin We help you to complete the proguard, multiDex and Manifest processing.

Add gradle dependency

In the project's build.gradle Medium, add tinker-patch-gradle-plugin Dependencies on

 buildscript { dependencies { classpath ( ' com.tencent.tinker:tinker-patch-gradle-plugin:1.9.1 ' ) } }

Then in the gradle file of the app app/build.gradle We need to add tinker library dependencies and apply tinker gradle plug-ins

 dependencies { // Optional, used to generate application classes provided( ' com.tencent.tinker:tinker-android-anno:1.9.1 ' ) // Tinker's core library compile( ' com.tencent.tinker:tinker-android-lib:1.9.1 ' )  } .. . .. . // Apply tinker plug-in apply plugin : ' com.tencent.tinker.patch '

Detailed explanation of gradle parameters

We call the original apk package the benchmark apk package. TinkerPatch directly uses the benchmark apk package to make a difference from the newly compiled apk package to get the final patch package. The parameters configured by gradle are explained in detail as follows:

parameter Default describe
tinkerPatch Configuration items related to global information
tinkerEnable true Whether to open tinker function.
oldApk null The path of the benchmark apk package must be entered, or an error will be reported.
newApk null Optional, used to compile the patch apk path. If the path is valid, that is, no new installation package will be compiled. Use oldApk and newApk to compile directly.
outputFolder null Optional, set the compilation output path. Default on build/outputs/tinkerPatch in
ignoreWarning false If the following conditions occur and ignoreWarning is false, we will interrupt the compilation. Because these situations may lead to risks in the compiled patch package:
1. minSdkVersion is less than 14, but dexMode The value of is "raw";
2. Four new components (Activity, BroadcastReceiver...);
3. Classes defined in dex.loader for loading patches are not in main dex;
4. The class defined in dex.loader for loading patches is modified;
5. resources.arsc is changed, but applyResourceMapping is not used for compilation.
useSign true In the running process, we need to verify whether the signature of the benchmark apk package is consistent with that of the patch package, and whether we need to sign for you.
buildConfig Compile related configuration items
applyMapping null Optional parameters; When compiling a new apk, we hope to reduce the size of the patch package by keeping the old apk's guard confusion. This is just a recommended setting, Not setting applyMapping will not affect any assembly compilation
applyResourceMapping null Optional parameters; When compiling a new apk, we want to use the old apk's R.txt The file keeps the allocation of ResId, which not only It can reduce the size of the patch package , also Avoid remote view exceptions due to ResId changes
tinkerId null During running, we need to verify whether the tinkerId of the benchmark apk package is equal to the tinkerId of the patch package. This is to determine which benchmark packages the patch package can run on. Generally, we can use git version number, versionName, etc.
keepDexApply false If we have multiple dexes, changes may increase due to class movement when compiling patches. If opened keepDexApply Mode. The patch package will be compiled according to the class distribution of the benchmark package.
isProtectedApp false Whether to use the hardening mode? Only the changed classes will be combined into patches. Note that this mode can only be used for hardening applications.
supportHotplugComponent( added 1.9.0 ) false Support adding non export activities
dex Configuration items related to dex
dexMode jar It can only be 'raw' or 'jar'.
For 'raw' mode, we will keep the format of input dex.
For 'jar' mode, we will recompress and encapsulate the input dex into jar. If your minSdkVersion is less than 14, you must select the 'jar' mode, which saves more storage space, but it takes more time to verify md5 than the 'raw' mode. By default, we do not check md5. Generally, we can select jar mode.
pattern [] You need to process the dex path, and support *? Wildcard, must be separated by '/'. The path is relative to the installation package, such as assets/
loader [] This item is very important. It defines which classes will be used when loading the patch package. These classes cannot be modified through Tinker, and must be placed in the main dex class.
The classes to be defined here are:
1. Application class defined by yourself;
2. Some classes in the Tinker library used to load the patch package, namely com. tencent. linker. loader. *;
3. If you have customized TinkerLoader, you need to add it and all the classes it references to the loader;
4. Other classes that you do not want to change, such as the BaseBuildInfo class in Sample. Note that the direct reference classes of these classes also need to be added to the loader. Or you need to make this class non verify.
five If the gradle version after 1.7.6 is used, parameters 1 and 2 will be filled in automatically. If you compile with newApk or command line version, 1 and 2 still need to be filled in manually
lib Configuration items related to lib
pattern [] You need to process the lib path, and support *? Wildcard, must be separated by '/'. Consistent with dex.pattern, the path is relative to the installation package, such as assets/
res Res related configuration items
pattern [] The res path needs to be processed, and supports *? Wildcard, must be separated by '/'. Consistent with dex.pattern, the path is relative to the installation package, such as assets/, It is important to note that only resources that meet the pattern will be placed in the synthesized resource package.
ignoreChange [] Support *? Wildcard, must be separated by '/'. If the pattern of ignoreChange is met, the addition, deletion and modification of the file will be ignored during compilation. In the most extreme case, ignoreChange is consistent with the above pattern, that is, all resource modifications will be completely ignored.
largeModSize one hundred For the modified resource, if it is greater than largeModSize, we will use the bsdiff algorithm. This can reduce the size of the patch package, but will increase the complexity of synthesis. The default size is 100kb
packageConfig Used to generate the 'package_meta.txt' file in the patch package
configField TINKER_ID, NEW_TINKER_ID ConfigField ("key", "value"). By default, we automatically read tinkerId from the Manifest of the benchmark installation package and the new installation package, and automatically write it to configField. Here, you can define other information. At runtime, you can get the corresponding value through TinkerLoadResult.getPackageConfigByName. However, it is recommended to modify the code directly, such as BuildConfig.
sevenZip 7zip path configuration item. The execution premise is that useSign is true
zipArtifact null For example, "com. tencent. mm: SevenZip: 1.1.10" will automatically obtain the corresponding 7za run file according to the machine attribute, which is recommended.
path 7za The 7za path in the system, such as "/usr/local/bin/7za". The path setting will overwrite the zipArtifact. If none is set, you will directly use 7za to try.

For specific parameter setting examples, refer to the app/build.gradle

Detailed explanation of tinkerPatch task

Direct use task:tinkerPatchVariantName (For example, tinkerPatchDebug, tinkerPatchRelease) can automatically select the corresponding compilation type according to Variant, and it also completes the following operations for us:

  1. Automatically insert TINKER_ID into the meta item of AndroidManifest, and the output path is build/intermediate/tinker_intermediates/AndroidManifest.xml;

  2. If minifyEnabled is true, Tinker's proguard rules will be automatically added to proguardFiles, and the output path is build/intermediate/tinker_intermediates/linker_proguard.pro, Here you don't need to copy them to your own proguard configuration file ;

  3. If multiDexEnabled is true, the keep rule that Tinker needs to place in the main dex will be automatically generated. Before tinker 1.7.6, you You need to manually copy the generated rules to your multiDexKeepProguard file For example, in Sample multiDexKeepProguard file("keep_in_main_dex.txt") After 1.7.6, it will be automatically processed through script, and there is no need to fill in manually.

  4. Open the jumboMode of dexOptions.

The output path is: build/intermediate/tinker_intermediates/linker_multidexkeep.pro. Then you can build/outputs/tinkerPatch The output file was found in.

Multi Flavor Packaging

Sometimes we want to package through the Flavor method. A simple usage example is provided in sample:

1. Compile through Flavor. At this time, we can see that the bakApk path is a directory distinguished by the name of Flavor;

2. Fill the compilation directory path into sample tinkerBuildFlavorDirectory , other fields do not need to be filled in, but will be automatically spliced according to the path;

 ext { tinkerBuildFlavorDirectory = "${bakPath}/app-1014-13-35-12" }

3. Operation tinkerPatchAllFlavorDebug perhaps tinkerPatchAllFlavorRelease You can get all the patches of Flavor.

Output File Details

In tinkerPatch output directory build/outputs/tinkerPatch The documents we are interested in are:

file name describe
patch_unsigned.apk Unsigned patch package
patch_signed.apk Signed patch package
patch_signed_7zip.apk The patch package that is signed and compressed with 7zip is also the one we usually use. But when it is officially released, it is better not to .apk At the end, avoid being hijacked by operators.
log.txt Console logs in the process of compiling patch packages
dex_log.txt Log about dex in the process of compiling the patch package
so_log.txt Log about lib during the process of compiling the patch package
tinker_result Finally, in the content of the patch package, including the diff's dex, lib, and meta files under assets
resources_out.zip The full resource apk that is finally synthesized on the mobile phone can be checked here to see if there are any missing files
tempPatchedDexes On the Dalvik and Art platforms, the complete Dex is finally synthesized on the mobile phone, We can view the products synthesized by dex here.

At the end of each compilation, we should check the relevant logs to understand the final files in the patch package. In particular, the patch files of dex, even 1k dex patch files, will also have two impacts: time consumption during synthesis and the ROM space volume of the synthesized complete dex files!

Command line access

Command Line Tools tinker-patch-cli.jar It provides the function of generating patch packages by making differences between the benchmark package and the new installation package. The specific command parameters are as follows:

 java - jar  tinker - patch - cli . jar - old  old . apk - new  new . apk - config  tinker_config . xml - out  output_path

The parameters are basically the same as those of gradle. For the new sign parameter, we need to enter the signature path and signature information.

Unlike gradle, we need to insert TINKER_ID into AndroidManifest.xml when compiling. for example

 < meta-data  android : name = " TINKER_ID "  android : value = " tinker_id_b168b32 " />

At the same time, we need to ensure that the guard file and the main dex class are correct. Refer to the following documents for specific configuration:

How to quickly obtain dependent packages

use tinker-git:buildTinkerSdk The task can be found in the buildSdk Get all the required files in the folder.

These include:

  1. build; The tools used in compiling are tinker-patch-cli.jar and some configuration information that may be used;
  2. android; It needs to be placed in the dependency library on the mobile phone, where tinker-android-anno.jar As an optional library, only those that use Tinker's annotation need to be imported.

Detailed usage steps

How to use Sample

Demo Please refer to tinker-sample-android , its use method is as follows:

  1. call assembleDebug Compile. We will save the compiled package in build/bakApk. Then we install it to the phone, click SHOW INFO Button, you can see that the patch has not been loaded

     Please enter a picture description here

  2. Modify the code, such as changing MainActivity in I am on patch onCreate The Log of is opened. Then we need to modify build.gradle Copy the path of the installation package compiled and saved in Step 1 to tinkerPatch In oldApk Parameter.

     Please enter a picture description here

  3. call tinkerPatchDebug , the patch package and related logs will be saved in /build/outputs/tinkerPatch/ Then we will patch_signed_7zip.apk Push to the sdcard of the mobile phone.

     adb  push ./ app / build / outputs / tinkerPatch / debug / patch_signed_7zip . apk / storage / sdcard0 /
  4. click LOAD PATCH Button, if you see patch success, please restart process To lock the screen or click KILL SELF Button

     Please enter a picture description here

  5. We can see that it does appear I am on patch onCreate Log, and click SHOW INFO The button shows that the patch package has been loaded successfully.

     Please enter a picture description here

How to use Release

Tinker is used as follows. Take the release packet accessed by gradle as an example:

  1. Backup the installation package and mapping file for each compilation or contracting;
  2. If there is a need for patch packs, modify your code, library files, etc. according to your own needs;
  3. Input the backup benchmark installation package and mapping file into the configuration of tinkerPatch;
  4. Run tinkerPatchRelease to automatically compile the latest installation package and make a difference from the input benchmark package to get the final patch package.

Debug source code

Tinker debugging source code is very simple. You need to run tinker group in the main project of tinker buildAndPublishTinkerToLocalMaven Task is enough.

In addition, since localmaven cannot transfer dependencies, the following libraries need to be explicitly referenced where they are used:

 compile ( "com.tencent.tinker:tinker-android-loader:${TINKER_VERSION}" ) { changing = true } compile ( "com.tencent.tinker:aosp-dexutils:${TINKER_VERSION}" ) { changing = true } compile ( "com.tencent.tinker:bsdiff-util:${TINKER_VERSION}" ) { changing = true } compile ( "com.tencent.tinker:tinker-commons:${TINKER_VERSION}" ) { changing = true }

github/Tinker The default branch of is the master branch. The meanings of the following are:

  1. Master branch; The last release of stable code, we tag the master branch;
  2. Dev branch; The development branch will contain the code of the next version. We can only provide pr for the dev branch and verify that some of the repaired issues have been repaired;
  3. Hotfix branch; To fix the branch of tinker's emergency bug.

For tinker branch management, issue and pr specifications, please read Tinker Contributing Guide

TinkerPatch patch management background

www.tinkerpatch.com It is the background of patch management developed by a third party based on CDN distribution. It provides functions such as script background hosting, version management, and transmission security, so that you can use Tinker immediately without setting up a background and caring about deployment operations.

In addition, TinkerPatch platform has added functions such as one click fool like access/compilation management optimization. Its Github address is TinkerPatch

In general, we recommend gradle as the access method. Then we continue to learn how to Tinker custom extension