View中Handler的应用
==问题==:View中mHandler实例是如何复用?在整个布局中所有的View都持有同一个View Handler么?还是同一个Activity下持有同一个实例?
-
android.view.View中有成员方法post(Runnable),其实质就是通过Handler的post方法,进行消息传递。通过包属性mAttachInfo持有的mHandler.post();
/** * <p>Causes the Runnable to be added to the message queue. * The runnable will be run on the user interface thread.</p> * * @param action The Runnable that will be executed. * */ public boolean post(Runnable action) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.post(action); } // Postpone the runnable until we know on which thread it needs to run. // Assume that the runnable will be successfully placed after attach. getRunQueue().post(action); return true; } AttachInfo mAttachInfo;
-
AttachInfo,是View中的一个静态内部类,是View相关信息的存储集合,其中就有mHandler属性。
/**//View中的静态内部类 * A set of information given to a view when it is attached to its parent * window. */ final static class AttachInfo { /** * A Handler supplied by a view's {@link android.view.ViewRootImpl}. This * handler can be used to pump events in the UI events queue. */ final Handler mHandler; }
-
View的mAttachInfo属性是在View的包成员方法dispatchAttachedToWindow()中被赋值的。
/** * @param info the {@link android.view.View.AttachInfo} to associated with * this view */ void dispatchAttachedToWindow(AttachInfo info, int visibility) { mAttachInfo = info; ... }
-
android.view.ViewRootImpl中有performTraversals(),通过host调用了View的dispatchAttachedToWindow方法,同时也为View传入了mAttachInfo对象,其中此方法的调用是在doTraversal()中进行的,同时也因为performTraversals()是私有方法,要想外部调用只能在别处有引用才能起作用。
View mView; private void performTraversals() { // cache mView since it is used so much below... final View host = mView; ... host.dispatchAttachedToWindow(mAttachInfo, 0); ... } void doTraversal() { if (mTraversalScheduled) { mTraversalScheduled = false; mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier); if (mProfile) { Debug.startMethodTracing("ViewAncestor"); } performTraversals(); if (mProfile) { Debug.stopMethodTracing(); mProfile = false; } } }
final class TraversalRunnable implements Runnable { @Override public void run() { doTraversal(); } } final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
-
android.view.ViewRootImpl,在构造器中就进行View.AttachInfo的初始化,并将mHandler对象传入,其中mHandler的实际类型是包权限内部类ViewRootHandler。
public ViewRootImpl(Context context, Display display) { mContext = context; ... mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this); ... } //初始化mHandler final ViewRootHandler mHandler = new ViewRootHandler(); //ViewRootHandler是ViewRootImpl的一个内部类 final class ViewRootHandler extends Handler {}
-
ViewRootImpl中方法setView,为其属性View mView 赋值
/** * We have one child */ public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { synchronized (this) { if (mView == null) { mView = view; ... } } }
网友评论