A sequence.
When the App reaches a certain size, quality optimization must be considered. There are small issues that seem to trigger only 0.01% of users, but if they happen in a product with over 10 million DAU, they’re a lot more serious.
Didi, a unicorn with a DAU of over 10 million, naturally has some unique optimization solutions. Didi recently opened source Booster, a quality optimization tool for Android App, on Github, which provides extensible capabilities through dynamic discovery and loading mechanisms. It’s a quality optimization framework for mobile applications.
Speaking of optimizations, I don’t know what the item will do. In terms of features, Booster enables performance testing and optimization, package size reduction, and code injection.
After a brief review, we found that the optimization currently supported is limited, but Good Booster provides convenient expansion capabilities. We can conduct targeted optimization according to business scenarios.
Although Booster has few optimization points at present, it provides a Roadmap for further development with open source, and its functions will be further improved. Here is a look at Didi’s new open source Booster.
The Booster.
2.1 What is Booster
Booster is an easy-to-use, lightweight, powerful and extensible quality optimization toolkit designed specifically for mobile applications that provides extensible capabilities through dynamic discovery and loading mechanisms. Is a mobile application quality optimization framework.
Booster consists of Transformer and Task.
Transformer is used to scan or modify bytecode (depending on the capabilities of Transformer), while Task is used to process resources under construction.
To meet the optimization requirements of different business scenarios, Booster provides the Transformer SPI and VariantProcessor SPI interfaces to allow developers to customize.
The overall framework of Booster is as follows:
Booster also has some minor version requirements for Gradle:
- Gradle 4.1 or later
- Android Gradle plugin 3.0 or later
2.2 What exactly does Booster do?
After reading the official concept, I still don’t know what Booster can do. Here, I take a Transformer that Booster supports as an example to explain what Booster can do.
Toast is a component that is often used in daily development, and in Android 7.0 it may trigger a BadTokenException. Booster can solve this problem.
Toast throws a BadTokenException that looks like the window’s Token is invalid at the time the Toast is displayed. It is also possible that the window has been destroyed at the time the Toast is displayed.
android.view.WindowManager$BadTokenException:
at android.view.ViewRootImpl.setView(ViewRootImpl.java)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java4)
at android.widget.Toast$TN.handleShow(Toast.java)
Copy the code
This problem only occurs in Android 7.0, and in later versions, the exception is directly caught to solve the problem. Here is the code for Android 8.0.
try {
mWM.addView(mView, mParams);
trySendAccessibilityEvent();
} catch (WindowManager.BadTokenException e) {
/* ignore */
}
Copy the code
Although there are some solutions to this problem, Booster gives us another option.
Booster has built-in Transformers, including booster-Transform-Bugfix-Toast, which is used to fix system errors caused by Toast in Android 7.0.
ToastBugfixTransformer’s main source code is here:
@AutoService(ClassTransformer::class)
class ToastBugfixTransformer : ClassTransformer {
override fun transform(context: TransformContext, klass: ClassNode): ClassNode {
klass.methods.forEach { method ->
method.instructions? .iterator()? .asIterable()? .filterIsInstance(MethodInsnNode::class.java)? .filter {
it.owner == TOAST && it.name == "show" && it.desc == "()V"
}? .forEach {
it.owner = `TOAST'`
it.desc = "(L$TOAST;) V"
it.opcode = Opcodes.INVOKESTATIC
}
}
return klass
}
}
private const val TOAST = "android/widget/Toast"
private const val `TOAST'` = "com/didiglobal/booster/$TOAST"
Copy the code
It is transfer the Toast of the system to another custom. A com didiglobal. Booster. The android. The Toast to solve under the widget package.
public static void show(final android.widget.Toast toast) {
if (Build.VERSION.SDK_INT == 25) {
workaround(toast).show();
} else {
toast.show();
}
}
private static android.widget.Toast workaround(final android.widget.Toast toast) {
final Object tn = getFieldValue(toast, "mTN");
if (null == tn) {
Log.w(TAG, "Field mTN of " + toast + " is null");
return toast;
}
final Object handler = getFieldValue(tn, "mHandler");
if (handler instanceof Handler) {
if (setFieldValue(handler, "mCallback".new CaughtCallback((Handler) handler))) {
return toast;
}
}
final Object show = getFieldValue(tn, "mShow");
if (show instanceof Runnable) {
if (setFieldValue(tn, "mShow".new CaughtRunnable((Runnable) show))) {
return toast;
}
}
Log.w(TAG, "Neither field mHandler nor mShow of " + tn + " is accessible");
return toast;
}
Copy the code
When API Level is not 25, toast.show () is directly called; when API Level is 25, toast.show () is called to determine the current Toast situation through reflection, and then return a valid Toast object.
Here we have fixed the Toast problem on 7.0. We don’t need to worry about using Toast during normal development, and we can distinguish quality assurance from business.
2.3 Booster Built-in functions
Booster has built several transformers and tasks into its open-source system. Booster’s booster-Transform-Bugfix-Toast is one of them.
Built-in Transformers
- Booster-transform-bugfix-toast: Fixed a system error caused by toast in 7.0.
- Booster-transform-lint: Checks for potential performance problems.
- Booster-transform-shrink: used to clear constants in the class file.
- Booster-transform-usage: scans the usage of a specific API.
Built-in Tasks
- Booster-task-artifact: Provides a task that displays an artifact.
- Booster-task-dependency: A task that displays identifiers for all dependencies and file paths.
- Booster-task-permission: Provides the Android permission to display the use of all dependencies.
The Transformer and Task functions provided by Booster are limited. They are more of a guide to the use of Booster through the source code.
Have more ideas to implement Transformer and Task yourself.
In the Roadmap released, iterations for the next few releases have been planned, focusing on: performance optimization, Lint, resource compression, user experience, and more. In terms of performance optimization, targeted optimization will be carried out on the use of multithreading, SP and WebView preloading.
Three. Summary moment
Overall, Booster is an excellent performance optimization framework that uses proven technologies and wraps them in a way that makes it easier to use. There is no pit too deep to try if necessary.
For more information, go to Github to read the Wiki and source code. If you are interested, don’t forget to click star.
Github:https://github.com/didi/booster
Did this article help you? Comments, likes, forwarding is the biggest support, thank you!
Public number background reply growth “growth”, will get the learning materials I prepared, can also reply “add group”, learning progress together; You can also reply to “questions” and ask me questions.