DroidAssist – A Lightweight, Configuration‑Based Java Bytecode Manipulation Framework for Android
DroidAssist, an open‑source, configuration‑driven framework from Didi, lets developers replace or augment Android Java bytecode at compile time via simple XML rules—enabling non‑intrusive mocking such as swapping SharedPreferences implementations without source changes or extra dependencies, while supporting incremental builds and rich transformation capabilities.
DroidAssist is an open‑source project released by Didi that provides a simple, non‑intrusive, configuration‑driven and lightweight way to manipulate Java bytecode on Android. Users only need to add a few lines of Java code in an XML configuration file to modify class files at compile time, without requiring any knowledge of bytecode or adding extra dependencies.
The passenger‑side app of Didi’s ride‑hailing platform integrates many business lines and third‑party libraries, leading to large code bases that are hard to trace and maintain. Frequent calls to SharedPreferences.apply() caused ANR issues due to the system’s QueuedWork.waitToFinish() blocking during activity or service lifecycle events. To eliminate this blocking, Didi decided to replace the system SharedPreferences with a custom implementation.
Two invasive approaches were considered: modifying every call to Context.getSharedPreferences(), or subclassing a common base class and overriding the method. Both required massive code changes and were hard to maintain. Instead, Didi sought a non‑intrusive mock tool that could intercept all getSharedPreferences() calls without touching the source code. Two possible techniques were evaluated:
Hook – high compatibility risk across devices.
AOP – existing AOP frameworks like AspectJ could not achieve the required mock behavior.
Consequently, Didi built DroidAssist, a bytecode‑modification based mock tool for Android.
Usage example
The following configuration replaces every call to Context.getSharedPreferences() with a custom implementation after compilation:
1 <Replace>
2 <MethodCall>
3 DroidAssist
4 <Source>android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String,int)</Source>
5 <Target>{$_= com.didi.quicksilver.QuicksilverPreferencesHelper.getSharedPreferences($0,$$);}</Target>
6 </MethodCall>
7 </Replace>Before transformation, the class looks like:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sp = getSharedPreferences("test", MODE_PRIVATE);
}
}After applying DroidAssist, the same class becomes:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sp = PreferencesHelper.getSharedPreferences(this, "test", MODE_PRIVATE); // The target method returns custom SharedPreferences
}
}For detailed usage and underlying principles, refer to the DroidAssist Wiki .
Key Features
Simple and configuration‑driven: add a plugin and define bytecode transformations in XML; no extra dependencies or source‑code changes are required.
Rich bytecode manipulation capabilities: replace, insert, surround, and enhance code (e.g., TryCatch, Timing).
Supports incremental builds with minimal impact on build time.
Q&A
1. What can DroidAssist do? It can perform code replacement, insertion, method mocking, logging replacement, SharedPreferences replacement, commit‑to‑apply conversion, dialog protection, device‑ID replacement, package‑info replacement, system‑service replacement, activity‑start protection, thread‑renaming, thread‑pool monitoring, main‑thread lag detection, folder‑creation monitoring, lifecycle timing, app‑startup timing, etc.
2. How does DroidAssist differ from AspectJ? DroidAssist uses a configuration‑based approach, requiring no Java annotations or source changes, and can easily achieve code‑replacement scenarios that are difficult for AspectJ. It can be used alone or together with AspectJ for more complex cases.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
