Tencent Tinker: hot-fix for Android dex, native libraries and resources without reinstalling the APK
Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstall apk.
At a glance
- What is it?
- Tinker is Tencent's hot-fix library for Android. It patches dex, native libraries and resources in place, but it cannot touch AndroidManifest.xml and it cannot be shipped through Google Play. This review covers the Gradle setup, the ApplicationLike indirection, the Ark variant and the cases where it is the wrong tool.
- Who is it for?
- Tinker fits teams that ship Android builds outside Google Play, or inside a distribution channel where dynamic code delivery is permitted, and that can live with the ApplicationLike indirection and the AndroidManifest.xml freeze. It does not fit apps distributed only through Google Play, since the README states the Developer Distribution Agreement forbids dynamic apk updates, and it does not fit projects that need to add activities, services or permissions after release.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The Android release problem Tinker was built to answer
Shipping a fix to an Android app normally means a new version, a store review, and a wait measured in days. Tinker attacks that gap directly: the README describes it as a hot-fix solution library that supports dex, library and resources update without reinstalling apk. The unit of delivery is a patch, not a full build, and the app applies it after launch.
The audience is narrow and specific. This is not a general Android utility. It is for teams that already ship at scale and have a release cadence slow enough that a bad string, a wrong resource or a crashing method cannot wait for the next store cycle. The repository topics list android, dynamic, hotfix and wechat, which points at the origin: Tencent built this for its own messaging app, where a full release is expensive. The sample module in the repository, tinker-sample-android, is the intended entry point, and the README repeatedly sends readers there rather than documenting every option in prose.
How Tinker loads a patch: ApplicationLike, TinkerApplication and the loader module
The mechanism is visible in the repository layout. tinker-android holds the Android side, split into a loader module (tinker-android-loader) and the main library, tinker-android-lib. The build side lives in tinker-build and tinker-commons. Patches are produced at build time by the Gradle plugin and consumed at runtime by the loader.
The runtime hook is an indirection around Application. Tinker does not let your Application class do the work. You move the logic into a class extending DefaultApplicationLike, and your real Application becomes a subclass of TinkerApplication. The README shows the constructor taking two arguments: a tinkerFlags value such as ShareConstants.TINKER_ENABLE_ALL, and the fully qualified name of your ApplicationLike class passed as a string. That string matters. The comment in the README explains it is passed as a string so the shell application does not have a binary dependency on your ApplicationLifeCycle class. The shell stays thin, and the loader can swap what sits behind it.
The flags argument is where you declare scope. ShareConstants.TINKER_ENABLE_ALL covers dex, library and resources. Narrower values exist for dex-only or library-only support, and the README lists them as the comment inside the constructor: dex only, library only, all support. Choosing the smallest scope you actually need is a design decision the README leaves to you.
There is a second way to wire this up. The tinker-android-anno artifact generates the Application class for you. You annotate your ApplicationLike with @DefaultLifeCycle and pass application and flags, and the annotation processor emits the class named in the application attribute. The README calls this the recommended route. It removes a hand-written file, but it adds an annotation processor to your build, which is a real cost in build time and in how much of the wiring is visible in source.
Installing Tinker: Gradle plugin, dependencies and a first patched build
The README gives the setup as Gradle snippets. First the plugin goes on the buildscript classpath in the root build.gradle. Note that the README's example pins 1.9.1 while the badge and release list show 1.9.15.1 as the current published version, so the snippet and the release metadata disagree and you should check which version you actually want.
buildscript {
dependencies {
classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.9.1')
}
}Then the app module applies the plugin and adds the libraries. The README marks tinker-android-anno as optional, describing it as help to generate the final application, and tinker-android-lib as the main Android lib.
dependencies {
provided('com.tencent.tinker:tinker-android-anno:1.9.1')
compile('com.tencent.tinker:tinker-android-lib:1.9.1')
}
apply plugin: 'com.tencent.tinker.patch'The provided and compile configurations in these snippets are the older Gradle names. On a current Android Gradle Plugin you will need to map them to compileOnly and implementation yourself; the README does not do that translation.
The third step is the code change. Your existing Application subclass is rewritten as a DefaultApplicationLike subclass, and a new Application class extends TinkerApplication with a no-arg constructor. The README is explicit that TinkerApplication is abstract with no default constructor, so the no-arg constructor is required, not stylistic.
public class SampleApplication extends TinkerApplication {
public SampleApplication() {
super(
ShareConstants.TINKER_ENABLE_ALL,
"tinker.sample.android.app.SampleApplicationLike");
}
}After that, the README points to SampleApplicationLike for how to install a patch and to the sample app/build.gradle for further configuration. It also states that proguard configuration is handled automatically and that Tinker generates the multiDex keep proguard file. That is a meaningful convenience: multidex keep rules are easy to get wrong and hard to debug. What the README does not provide is a minimal end-to-end walkthrough outside the sample module, so expect to read the sample's build file rather than follow a step list.
The Ark variant and its two-part patch APK
Tinker has a second target beyond standard Android. The README documents an Ark path, where patches are built with a shell script rather than the Gradle plugin:
bash build_patch_dexdiff.sh old=xxx new=xxxThe old argument is the absolute path of the buggy apk and new is the absolute path of the fixed apk, and the README notes both are not compiled by Ark. The resulting patch is packaged in an APK. Compilation on the Ark side is marked TODO in the README, with the note that it is currently compiled by the Ark compiler team and that the output patch is packaged in APK format without signature.
Packaging differs by tool. With tinker-cli you add an issue block to tinker_config.xml with an id of arkHot, a path value and a name value. With Gradle you add an ark block to app/build.gradle with path and name. Both default to a path of arkHot and a name of patch.apk when you omit them.
The final patch APK for this path contains two files: classes.dex for Android and patch.apk with the .so files for Ark. That two-file structure is the part worth internalising, because it means your patch delivery and verification has to account for native code separately from dex code. The unsigned output is also a gap: the README states the patch is unsigned, so whatever signing or integrity check you need is on you.
What Tinker cannot patch, and where it is the wrong tool
The README has a section titled Tinker Known Issues, and it is blunt. Three items are listed.
First, AndroidManifest.xml cannot be updated. Adding an Android component, an activity, a service, a receiver or a provider, is off the table. Anything that requires a new manifest entry requires a real release. This is the constraint that most often decides the question, because a large share of urgent fixes involve a new component or a permission.
Second, some Samsung models running android-21 are not supported. The README does not enumerate the models. If your install base includes that combination, you cannot assume the patch applies, and the README gives you nothing to test against beyond the OS version and vendor.
Third, the README states that due to the Google Play Developer Distribution Agreement, Tinker cannot be used to dynamic update an apk distributed through Play. That is not a technical limitation, it is a distribution one, and it removes the single largest Android channel from the picture. If your app ships only on Play, Tinker's core value proposition does not apply to you at all.
There is a fourth gap the README does not list under Known Issues but implies elsewhere: the Ark path produces an unsigned patch and its Ark-side compilation is still a TODO. Treat that path as less finished than the standard Android one.
A subtler cost is the Application indirection itself. Moving logic out of Application into an ApplicationLike changes your app's startup shape, and every developer on the team has to know why. That is a permanent tax on onboarding, paid for the ability to patch at runtime.
Tinker against Android App Bundles and Play Feature Delivery
The obvious alternative is not another hot-fix library. It is the platform's own delivery machinery: Android App Bundles with Play Feature Delivery, where Google Play generates and serves split APKs and can deliver modules on demand or on condition. The difference in approach is fundamental. Tinker patches code and resources inside an installed app at runtime, after the fact, without a store round trip. App Bundles change what gets installed in the first place, but every change still goes through Play review and a user-side update.
That difference decides the use case. If your problem is release latency, App Bundles do not solve it; the review cycle remains. If your problem is download size or delivering optional features, Tinker is the wrong shape entirely, because it assumes a base APK is already installed and only ships a delta on top. Tinker also carries the compliance problem the README names, while App Bundles are the sanctioned path.
The honest framing is that these are complementary rather than competing. A team using App Bundles for distribution can still want a patch channel for the cases where a fix cannot wait, provided their distribution agreement allows it. What Tinker is not is a replacement for a release process. It is a narrow escape hatch with a documented list of things it cannot reach.
Maintenance, versioning and the BSD licence question
The repository is not archived, and the last push was on 2026-08-12. That is recent enough that the project is not dormant. Release history tells a different story about cadence: v1.9.15 and v1.9.15.1 both landed on 2024-12-09, and v1.9.15.2 arrived on 2025-07-07. The 1.9.x line has been the version family for a long time, and the README's own install snippets still reference 1.9.1. Anyone adopting should pin an explicit version rather than copy the snippet, and should check the release list for the artifact they intend to use.
Upgrade cost is mostly a Gradle problem. The plugin is applied through the legacy com.tencent.tinker.patch plugin id, and the dependency snippets use provided and compile. Moving to a current Android Gradle Plugin means reworking those configurations, and any change to how the Application class is generated, whether by hand or through tinker-android-anno, touches the app's entry point. That is not a drop-in dependency you can bump without reading the diff.
On licensing, the repository metadata reports NOASSERTION, while the README states Tinker is under the BSD license and links the LICENSE file, and the README badge shows BSD3. The two signals do not match, so the machine-readable licence field is not authoritative here. If the licence terms matter to your legal review, read the LICENSE file in the repository root directly rather than relying on either the badge or the metadata field. This is a description of what the repository says, not legal advice.
Editorial conclusion
Tinker fits teams that ship Android builds outside Google Play, or inside a distribution channel where dynamic code delivery is permitted, and that can live with the ApplicationLike indirection and the AndroidManifest.xml freeze. It does not fit apps distributed only through Google Play, since the README states the Developer Distribution Agreement forbids dynamic apk updates, and it does not fit projects that need to add activities, services or permissions after release. Before adopting, verify three things against your own build: that your Application class can be rewritten as a DefaultApplicationLike subclass, that your minSdk and device matrix avoid the Samsung android-21 models the README lists as unsupported, and that your release pipeline can carry the patch APK alongside the base APK, including the separate patch.apk that Ark builds contain.
Frequently asked questions
How do I install Tinker in an Android project?
Add the tinker-patch-gradle-plugin to the buildscript classpath in the root build.gradle, then add tinker-android-lib and optionally tinker-android-anno to the app module and apply the com.tencent.tinker.patch plugin. The README's snippets pin version 1.9.1 and use the older provided and compile configurations.
Does Tinker work with apps distributed through Google Play?
The README states that due to the Google Play Developer Distribution Agreement, Tinker cannot be used to dynamic update an apk, and lists this under Tinker Known Issues. That makes Play-distributed apps a poor fit for its core purpose.
What can Tinker not update at runtime?
The README's Known Issues section says AndroidManifest.xml cannot be updated, so you cannot add an Android component this way. It also lists some Samsung models on android-21 as unsupported.
What licence is Tinker released under?
The README says Tinker is under the BSD license, links the LICENSE file, and its badge shows BSD3, while the repository metadata reports NOASSERTION. Read the LICENSE file in the repository root to resolve the difference.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tencent-tinker)