android(五)、 ViewRoot触摸事件流程

来源:互联网 发布:进出口总额 英文数据 编辑:程序博客网 时间:2024/05/23 13:00

本文主要内容:

       ViewRoot是为WindowManagerGlobal而设计的,它承担了View和WindowManger沟通的角色,属于View顶层设计。ViewRoot的工作包括但不限于-触摸事件分发,view树的绘制事件分发,测绘事件的分发,布局事件的分发。

第一、ViewRoot的触摸事件分发


   准备工作:那首先就要说下Activity是如何通过ViewRoot显示到界面上的。

    Activity的attach()大致干了三件事:

1、创建Window对象(PhoneWindow)

2、为window对象设置CallBack回调对象,非常重要

3、为window对象设置WindowManger管理者,WindowManager对象是在ContextImpl类第一次被加载进时创建的(静态域),实际为WindowManagerImpl对象。

Activity的attach()方法体如下:

5053    final void attach(Context context, ActivityThread aThread,5054            Instrumentation instr, IBinder token, int ident,5055            Application application, Intent intent, ActivityInfo info,5056            CharSequence title, Activity parent, String id,5057            NonConfigurationInstances lastNonConfigurationInstances,5058            Configuration config) {5059        attachBaseContext(context);50605061        mFragments.attachActivity(this, mContainer, null);5062        5063        mWindow = PolicyManager.makeNewWindow(this);5064        mWindow.setCallback(this);5065        mWindow.getLayoutInflater().setPrivateFactory(this);5072        mUiThread = Thread.currentThread();5085        mLastNonConfigurationInstances = lastNonConfigurationInstances;50865087        mWindow.setWindowManager(5088                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),5089                mToken, mComponent.flattenToString(),5090                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);5091        if (mParent != null) {5092            mWindow.setContainer(mParent.getWindow());5093        }5094        mWindowManager = mWindow.getWindowManager();5095        mCurrentConfig = config;5096    }

Activity显示工作:

      上述过程明显Activity并没有把自己显示到界面上。Activity实际上并不控制自己的显示,由它的控制引擎(framework框架)来管理。

      Activity的显示实际工作是ActivityThread完成的,在ActivityThread的handleResumeActivity方法中核心代码如下:

2796                r.window = r.activity.getWindow();2797                View decor = r.window.getDecorView();2798                decor.setVisibility(View.INVISIBLE);2799                ViewManager wm = a.getWindowManager();2800                WindowManager.LayoutParams l = r.window.getAttributes();2801                a.mDecor = decor;2802                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;2803                l.softInputMode |= forwardBit;2804                if (a.mVisibleFromClient) {2805                    a.mWindowAdded = true;2806                    wm.addView(decor, l);2807                }

完成的主要工作如下(完成Activity的显示工作):

1、获取Activity中的window对象。

2、获取Activity中的DecorView。

3、获取Activity中的WindowManger对象,a为r.activity。

4、将DecorView添加到WindowMangerImpl中。

5、WindowManagerImpl添加DecorView对象,添加过程中又用ViewRootImpl包装了一下。


ViewRootImpl分发事件

那么ViewRootImpl是如何分发事件的,由于方法体较长,所以删除了一部分留下了我们比较关注的主题部分:

 private void deliverPointerEvent(QueuedInputEvent q) {3178        final MotionEvent event = (MotionEvent)q.mEvent;3179        final boolean isTouchEvent = event.isTouchEvent();3219        // Dispatch touch to view hierarchy.3220        boolean handled = mView.dispatchPointerEvent(event);3221        if (MEASURE_LATENCY) {3222            lt.sample("B Dispatched PointerEvents ", System.nanoTime() - event.getEventTimeNano());3223        }3224        if (handled) {3225            finishInputEvent(q, true);3226            return;3227        }32283229        // Pointer event was unhandled.3230        finishInputEvent(q, false);3231    }3232

首先会不停的从触摸消息的消息队列中取出消息体,然后事件给了DecorView对象,那么把DecorView的事件分发方法体也放出来吧!!!

  • CallBack处理了事件--cb.dispatchTouchEvent();
  • DecorView的父类处理了触摸事件--super.dispatchTouchEvent();
  • CallBack处理在前,DecorView父类处理在后。

 @Override1899        public boolean More ...dispatchTouchEvent(MotionEvent ev) {1900            final Callback cb = getCallback();1901            return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev)1902                    : super.dispatchTouchEvent(ev);1903        }1904


     此处CallBack为Activity,因为Activity的attch方法把自身作为callBack对象传给了Window对象,这里的getCallBack方法就是获取WIndow的CallBack对象。


Activity中

      一、Activity会首先处理事件。

      二、DecorView为第二个处理事件的。

      三、假设事件没有消耗,那么事件将返回到ViewRootImpl中,ViewRootImpl发现并没有View消耗事件,便执行了事件的销毁方法finishInputEvent(q, false);

非Activity

      一、DecorView为第一个处理事件的。

      二、假设事件没有消耗,那么事件将返回到ViewRootImpl中,ViewRootImpl发现并没有View消耗事件,便执行了事件的销毁方法finishInputEvent(q, false);


0 0
原创粉丝点击