Startup window optimization

After launching the app, a blank launch window is displayed. You can give this window a background image instead of a white screen (with the Theme setting).

Asynchronous tasks

1. Initialize logic abstracted into tasks

2. According to the dependencies of tasks, BFS (breadth first) is used to construct directed acyclic graphs, and topological ordering is obtained to obtain the execution order of tasks.

1.1. Firstly, find all queues with an entry degree of 0 and store them in the queue variable

1.2. When the queue is not empty, circular judgment is performed.

  • Pop out of the queue and add to the result queue

  • Iterate over the subtasks of the current task, notifying them that their input is reduced by one (actually traversing taskChildMap), and if the input is zero, add it to the queue

1.3, if the result queue and list size are not equal, prove the existence of a ring

3. In the process of multi-threaded execution, task dependency and CounDownLatch are used to ensure the sequential execution relationship

Suppose a is a pre-task of B, when a task B is executed:

2.1 if CounDownLatch is greater than 0, it indicates that pre-task A is not finished and task B is waiting.

2.2. When pre-task A is completed, notify task B that the CounDownLatch of task B is reduced by one.

2.3. If the CounDownLatch of task B is 0, perform task B.

The CounDownLatch of the task is the number of pre-tasks. The pre-task list of the current task is set during the initialization of the task. Therefore, you can obtain the pre-task list and the number of pre-tasks through the current task.

The real Task is DispatchRunnable, which holds the Task and calls the Task’s run method in its run method.

Await method is also implemented by using CounDownLatch to record NeedWait task number. NeedWait task will be subtracted by 1 after execution. If CounDownLatch is 0, the next task (task after topology task) will be performed.

Note: Asynchronous tasks must use thread pools to avoid excessive threads and CPU switching

Delayed tasks

public class DelayInitDispatcher { private Queue<Task> mDelayTasks = new LinkedList<>(); private MessageQueue.IdleHandler mIdleHandler = new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { if(mDelayTasks.size()>0){ Task task = mDelayTasks.poll(); new DispatchRunnable(task).run(); } return ! mDelayTasks.isEmpty(); }}; public DelayInitDispatcher addTask(Task task){ mDelayTasks.add(task); return this; } public void start(){ Looper.myQueue().addIdleHandler(mIdleHandler); }}Copy the code

Handler().postdelayed () pain point:

1. Timing is not easy to control: Handler postDelayed the specified delay time is not easy to estimate.

2, the interface UI is stuck: the user may still be sliding the list.

With IdleHandler, this Handler is only called when it is idle. If true, this Handler is always executed. If false, this Handler is removed from the message queue.

When the CPU is idle, execute lazy-initialized tasks, one by one, and pull them out and execute them. The advantage of batch execution is that each task occupies the main thread for a relatively short period of time and the CPU is free, thus avoiding UI lag more effectively.

Note that tasks that can be asynchronously loaded (or that must be executed before the onCreate method of the Application is completed) are loaded using asynchronous initiators in the onCreate method of the Application. Tasks that cannot be asynchronously loaded are loaded using asynchronous initiators. We can use a lazy initiator for loading. If the task can be loaded at time, use lazy loading.

Question: What if a user uses a library that has not been initialized?

Class rearrangement

The order of classes in Dex is adjusted through the Interdex of ReDex, and the classes that need to be loaded at startup are placed in the main Dex in sequence. Specific implementation can refer to Redex preliminary and Interdex: Andorid cold start optimization.

Tik Tok BoostMultiDex optimization

For systems up to 5.0:

The specific implementation principle is as follows: At the first startup, the original DEX without OPT optimization is directly loaded so that the APP can start normally first. Then start a separate process in the background to slowly complete the OPT work of DEX and avoid affecting the normal use of the foreground APP as much as possible. The solution of directly loading DEX bypassing ODEX is as follows:

1) Extract the bytecode of the original Secondary DEX file from APK; 2) obtain dvm_dalvik_system_DexFile array from DLSYM Query the Dalvik_dalvik_system_DexFile_openDexFile_bytearray function in the array. 4) Call this function and pass in the DEX bytecode obtained from APK one by one to complete the DEX loading. 5) Add DexFile objects to the pathList of APP PathClassLoader

Main page data is preloaded

In the case of splash page, asynchronous tasks are used to request the data of the main page in advance. When the main page is loaded, it can be directly read from the memory.

Flash page and home page drawing optimization

1. Analyze layouts to reduce nesting or replace FrameLayout, constraintLayout

2. Use include+ Merge to reduce layout levels

3. Use viewStub to provide on-demand loading

4. Reuse winOW Background resources of the system

Memory optimization prevents GC from consuming CPU time

Reduce the number of GC during startup

1. Avoid extensive string operations, especially serialization and deserialization

2. Frequently created objects need to be considered for reuse

3. Move to Native implementation

Reduce the number of cold starts

MainActivity returns hide instead of destroy

 override fun onBackPressed() {
        //super.onBackPressed()
        moveTaskToBack(true)
    } 
Copy the code

The webview optimization

If the main page is opened, the WebView shows the advertisement.

1. Webview initialization and reuse in advance

2. Use offline packages

3. Use data preloading

reference

In-depth exploration of Android startup speed optimization Android App startup optimization

Android Startup Optimization (4) – AnchorTask is implemented

www.androidperformance.com/2019/11/18/…