Detailed explanation of Android startup optimized delayed loading steps

  • 2021-11-02 02:14:04
  • OfStack

Preface

When the application starts, in order to speed up the startup, it is often necessary to put some heavy operations into sub-threads, or delay loading. Putting tasks in sub-threads is a relatively simple and seemingly effective operation, but you can't rely too much on sub-threads. Although it won't block the main thread, it will preempt CPU with the main thread. When there are many sub-threads and the task is heavy, it will still slow down the main thread. If you don't believe it, you can type Systrace to see 1. Delayed loading is also a better strategy, but the difficulty lies in how long the delay is, which is not easy to control.

The following words are not much to say, let's take a look at the detailed introduction

IdleHandler

In the past, I was thinking about why Android didn't provide an interface in Activity or Fragment, so that we could perform some operations when the main thread was idle. Later, I found that there was, but this interface was not in Activity and Fragment, but in MessageQueue. You can see such an interface in the source code of MessageQuque:


/**
* Callback interface for discovering when a thread is going to block
* waiting for more messages.
*/
public static interface IdleHandler {
 /**
 * Called when the message queue has run out of messages and will now
 * wait for more. Return true to keep your idle handler active, false
 * to have it removed. This may be called if there are still messages
 * pending in the queue, but they are all scheduled to be dispatched
 * after the current time.
 */
 boolean queueIdle();

}

To put it simply, when there is no more message in MessageQueue, the method queueIdle () will be called back. If true is returned, the method will continue to be called back when there is no message in MessageQueue. If false is returned, the listening will be removed after execution.

The principle is so simple, the next step is to optimize the code, and the code is also very simple.


@Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 // ...

 //  Get the main thread MessageQueue
 Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {

 @Override
 public boolean queueIdle() {
  //  Here to deal with what you want to delay loading 
  delayLoad();

  //  Final return false , follow-up no longer need to monitor. 
  return false;
 }
 });
}

It is not difficult to write 1 point, but we need to master such a knowledge point. One more sentence here, Many articles on cold start optimization on the Internet talk about the lazy loading of ViewPager. That is, wait until the user slides past before loading the interface. We did the same at the beginning of the project, but in fact, this experience is really bad, so we used IdleHandler to do a delayed loading, which does not affect the startup of the main interface, and can load other Tab immediately when the main thread is idle, so as to find the best balance between performance and experience.

References

Do you know MessageQueue. IdleHandler of android?

Summarize


Related articles: