Correct use and analysis of handler for Android performance optimization

1. What is Handler

    It is the upper interface of the Android message mechanism and a mechanism for updating the ui.
   (Android is thread-unsafe, so it can update the ui in the child thread, but only time-consuming operations can be performed, so message updates must be sent through the handler)

2. Handler implementation principle

ThreadLocal: Access the same ThreadLocal through different threads. Whether it is the get or set method of ThreadLocal, their read and write operations to ThreadLocal are limited to their respective threads.
Save the Looper through ThreadLocal (to ensure that each Looper in the handler is independent of each other, and different threads access different Loopers)
Looper manages the MessageQueue internally.

Each handler must be associated with the main thread before it can update the ui. Handlers cannot be created in inner classes. This ensures that the UI thread is thread-safe.

(Just a little reference to another blogger's picture to show the process of the handler, I personally think it's pretty good)



3.Handler memory leak problem


Cause of memory leak: Static inner class holds anonymous use of outer class, which leads to some time-consuming operations inside the handler still running when the user exits the current Activity, which causes the activity to be referenced by the handler, and eventually causes the activity to remain in the handler. The stack is not reclaimed, resulting in a memory leak.

Solution: 1. The handler internally holds a weak reference to the external activity.
             2. Change the handler to a static inner class.
             3. Use mHandler.removeCallBack() in the activity's onDestory method.

           (only 90% solution)

Solution example:

/**
 * Solution
 *
 * To solve this problem, the idea is not to apply non-static inner classes. When inheriting Handler, either place it in a separate class file or use static inner classes.
* Because the static inner class does not hold a reference to the outer class, it will not cause memory leaks of the outer class instance.
* When you need to call an external Activity in a static inner class, we can use a weak reference to handle it.
* In addition, you also need to set Runnable as a static member property.
* Note: A static anonymous inner class instance does not hold a reference to the outer class.
*/
 private MyHandler mMyHandler = new MyHandler( this );


private static class MyHandler extends Handler{

   // SoftReference<Activity> can also use soft applications. It will only be recycled when there is insufficient memory
 private final WeakReference<Activity> mActivity ;    

    private MyHandler(Activity activity) {
        mActivity = new WeakReference<>(activity);
    }

    @Override
public void handleMessage(Message msg) {    
        Activity activity = mActivity.get();
        if (activity != null){
            //做操作
        }
        super.handleMessage(msg);
    }
}

private static final Runnable sRunnable = new Runnable() {
    @Override
public void run() {
        //做操作
}        
};
 
 

It feels good, give it a thumbs upSmile

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325509856&siteId=291194637