android的MessageQueue.IdleHandler


声明:本文转载自https://my.oschina.net/android520/blog/1791335,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

MessageQueue内部有个IdleHandler接口,具体定义如下:

   /**      * 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();     } 

简而言之,就是在looper里面的message暂时处理完了,这个时候会回调这个接口,返回false,那么就会移除它,返回true就会在下次message处理完了的时候继续回调。

下面先通过个例子来直观看下IdleHandler的执行时机。

public class IdleHandleActivity extends Activity {      public static final String TAG = "IdleHandleActivity";      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         Log.d(TAG, "onCreate");         setContentView(R.layout.activity_idle_handler);          Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {             @Override             public boolean queueIdle() {                 Log.d(TAG, "IdleHandler post");                 return false;             }         });          new Handler().post(new Runnable() {             @Override             public void run() {                 Log.d(TAG, "Handler post1");             }         });         new Handler().post(new Runnable() {             @Override             public void run() {                 Log.d(TAG, "Handler post2");             }         });         new Handler().postDelayed(new Runnable() {             @Override             public void run() {                 Log.d(TAG, "Handler delay post");             }         }, 500);     }      @Override     protected void onStart() {         super.onStart();         Log.d(TAG, "onStart");     }      @Override     protected void onResume() {         super.onResume();         Log.d(TAG, "onResume");     } } 
public class MyView extends TextView {      ......      @Override     protected void onFinishInflate() {         super.onFinishInflate();         Log.d(IdleHandleActivity.TAG, getText() + " onFinishInflate");     }      @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         super.onMeasure(widthMeasureSpec, heightMeasureSpec);         Log.d(IdleHandleActivity.TAG, getText() + " onMeasure");     }      @Override     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {         super.onLayout(changed, left, top, right, bottom);         Log.d(IdleHandleActivity.TAG, getText() + " onLayout");     }      @Override     protected void onDraw(Canvas canvas) {         super.onDraw(canvas);         Log.d(IdleHandleActivity.TAG, getText() + " onDraw");     } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical"     tools:context="com.outman.example.androidtest.MainActivity">      <com.outman.example.androidtest.MyView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="MyView!"/>  </LinearLayout> 

执行结果:

04-08 17:30:33.994 16452-16452/ D/IdleHandleActivity: onCreate 04-08 17:30:34.038 16452-16452/ D/IdleHandleActivity: MyView! onFinishInflate 04-08 17:30:34.068 16452-16452/ D/IdleHandleActivity: onStart 04-08 17:30:34.073 16452-16452/ D/IdleHandleActivity: onResume 04-08 17:30:34.089 16452-16452/ D/IdleHandleActivity: Handler post1 04-08 17:30:34.089 16452-16452/ D/IdleHandleActivity: Handler post2 04-08 17:30:34.097 16452-16452/ D/IdleHandleActivity: MyView! onMeasure 04-08 17:30:34.106 16452-16452/ D/IdleHandleActivity: MyView! onMeasure 04-08 17:30:34.107 16452-16452/ D/IdleHandleActivity: MyView! onLayout 04-08 17:30:34.125 16452-16452/ D/IdleHandleActivity: MyView! onDraw 04-08 17:30:34.136 16452-16452/ D/IdleHandleActivity: IdleHandler post 04-08 17:30:34.569 16452-16452/ D/IdleHandleActivity: Handler delay post 

通过执行结果可以看到

1. IdleHandler的回调在,所有Handler执行完MessageQueue中的内容,再执行

2. IdleHandler的回调在,Activity执行完onResume方法,再执行

3. IdleHandler的回调在,初始化完View后,即执行完onDraw后,再执行

在Glide和LeakCanary中都有IdleHandler的使用

Glide中

// Responsible for cleaning up the active resource map by remove weak references that have been cleared.     private static class RefQueueIdleHandler implements MessageQueue.IdleHandler {         private final Map<Key, WeakReference<EngineResource<?>>> activeResources;         private final ReferenceQueue<EngineResource<?>> queue;          public RefQueueIdleHandler(Map<Key, WeakReference<EngineResource<?>>> activeResources,                 ReferenceQueue<EngineResource<?>> queue) {             this.activeResources = activeResources;             this.queue = queue;         }          @Override         public boolean queueIdle() {             ResourceWeakReference ref = (ResourceWeakReference) queue.poll();             if (ref != null) {                 activeResources.remove(ref.key);             }              return true;         }     }

LeakCanary中

private void showToast(final FutureResult<Toast> waitingForToast) {     mainHandler.post(new Runnable() {       @Override public void run() {         final Toast toast = new Toast(context);         toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);         toast.setDuration(Toast.LENGTH_LONG);         LayoutInflater inflater = LayoutInflater.from(context);         toast.setView(inflater.inflate(R.layout.leak_canary_heap_dump_toast, null));         toast.show();         // Waiting for Idle to make sure Toast gets rendered.         Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {           @Override public boolean queueIdle() {             waitingForToast.set(toast);             return false;           }         });       }     });   }

 

参考 https://mp.weixin.qq.com/s/KpeBqIEYeOzt_frANoGuSg

 

本文发表于2018年04月08日 22:38
(c)注:本文转载自https://my.oschina.net/android520/blog/1791335,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1997 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1