Activity分发源码分析
2018-07-28 本文已影响20人
Utte
Activity分发机制
Activity # dispatchTouchEvent(MotionEvent ev)
public boolean dispatchTouchEvent(MotionEvent ev) {
// 判断是否为ACTION_DOWN事件。
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
//此方法为空实现,当此activity在栈顶时,触屏点击按home,back,menu键等都会触发此方法。
// 注释说当此Activity运行时,如果你想知道用户与此有交互,就实现此方法。
// public void onUserInteraction() {
// }
}
if (getWindow().superDispatchTouchEvent(ev)) {
// 获取当前Activity的Window。
// public Window getWindow() {
// return mWindow;
// }
// 调用当前Window对象的superDispatchTouchEvent(ev),Window的真正实现类是PhoneWindow,
// 所以实际调用的是PhoneWindow的superDispatchTouchEvent(ev)。
// PhoneWindow又调用了顶级View的superDispatchTouchEvent(event)。
// @Override
// public boolean superDispatchTouchEvent(MotionEvent event) {
// return mDecor.superDispatchTouchEvent(event);
// }
// 顶级View的父类是FrameLayout,FrameLayout的父类是ViewGroup。
// FrameLayout没有重写dispatchTouchEvent(event),
// 所以此处调用了ViewGroup的dispatchTouchEvent(event)。
// 完成了从Activity到ViewGroup的事件传递,
// 接受了ViewGroup的dispatchTouchEvent(event)的返回值,
// 表示在向下分发的过程中,存在View消耗了此事件。
//public boolean superDispatchTouchEvent(MotionEvent event) {
// return super.dispatchTouchEvent(event);
//}
return true;
// 如果ViewGroup的dispatchTouchEvent(event)返回了true,也就是有View消耗了该事件,
// 那么Activiy的dispatchTouchEvent()就返回true,完成了整个事件分发过程。
// 否则继续。
}
return onTouchEvent(ev);
// 此时代表在事件向下分发过程中没有View消耗该事件,就Activity自己消耗该事件。
// 调用Activity的onTouchEvent(ev)。
}
Activity # onTouchEvent(MotionEvent event)
// Activity向下分发中没有任何View消耗该事件时被调用
// Activity本身尝试消耗
public boolean onTouchEvent(MotionEvent event) {
if (mWindow.shouldCloseOnTouch(this, event)) {
// 判断是否是DOWN事件,event的坐标是否在边界内等。
// 如果是,就消耗事件返回true,否则不消耗返回false。
// public boolean shouldCloseOnTouch(Context context, MotionEvent event) {
// if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN
// && isOutOfBounds(context, event) && peekDecorView() != null) {
// return true;
// }
// return false;
// }
finish();
// 分发完成,结束。
return true;
// 返回true,事件已经被Activity消耗。
}
return false;
//返回false,因为事件没有被消耗。
}
过程总结
- 一个点击事件开始后会调用到Activity的dispatchTouchEvent()。
- Activity的会将事件传递给Window的superDispatchTouchEvent(),这个方法的实现在PhoneWindow中。
- PhoneWindow将时间继续传递,调用了DecorView的superDispatchTouchEvent()。
- DecorView将事件传递给父类,调用了ViewGroup的dispatchTouchEvent(),交给ViewGroup继续向下分发。
- 如果向下分发过程中事件被消耗,那么Activity分发过程结束,Activity的dispatchTouchEvent()返回true。
- 如果没有被消耗,则调用Activity的onTouchEvent()。
- onTouchEvent()中判断了事件是否为ACTION_DOWN、是否在边界内等,如果是就消耗该事件,返回true,Activity的dispatchTouchEvent()也返回true,分发完成。
- 如果不符合判断,则Activity也不消耗,返回false,Activity的dispatchTouchEvent()返回false,分发完成。