记的以前写过系统如何在驱动中生成消息,包装消息,丢到消息队列。现在和大家交流下,消息如何在AP中传递。
系统会根据PID 把消息分发到当前进程的Active的 Activity.
在Activity首先收到消息的是public boolean dispatchKeyEvent(KeyEvent event); 该函数首先把消息送给与Activity帮定的Window.
Window win = getWindow();
if (win.superDispatchKeyEvent(event))
可以看到Window.java里的superDispatchKeyEvent 是个抽象方法,实现在PhoneWindow.java里
public boolean superDispatchKeyEvent(KeyEvent event) {
mDecor.superDispatchKeyEvent(event);
}
mDecor是个什么东西,这个东西是个根ViewGroup 从FrameLayout继承来的。那它什么时候初始化的呢?
它是在setContentView()时候,也就是你要显示画面的时候,系统先为我们生成的。然后系统解释xml
通过JNI产生view对象,读取布局参数,new出viewgroup.layoutparams。然后用addView根据层次结构,按照布局参数信息(view 大小位置等)显示画面。我们写的xml的跟view是添加到了某个VIEW里,这个view暂时叫changer吧,然后把changer添加到这个mDecor里。完成了画面显示。
有人要问,这个changer view哪来的呢?是系统根据你设置的Flags 叫了系统里的一个xml来产生的,可以参考PhoneWindow.java里的
ViewGroup generateLayout(DecorView decor);函数实现。
有扯远了,怎么回事呢?
mDecor把消息引进了View层次结构里了。开始
public boolean superDispatchKeyEvent(KeyEvent event) {
return super.dispatchKeyEvent(event);
}
这个东西会进入FrameLayout里,代表了这个super. 然后系统会找到当前有焦点的view. 叫了View.java里的
public boolean dispatchKeyEvent(KeyEvent event)这个函数。
这个函数会检测当前的view 是否注册了Listener. if (mOnKeyListener != null &&
如果注册了,就继续叫OnkeyListener的onKey接口。
如果没有,就叫event.dispatch . 它会叫到KeyEvent.java里的dispatch方法。这个方法具体实现是
public final boolean dispatch(Callback receiver, DispatcherState state,
Object target)
第一次参数是CallBack 接口。会调用receiver.onKeyDown(mKeyCode, this);这个东西, 这个比较麻烦,Callback 是接口,它会调用哪个具体实现呢?
呵呵,叫了AP 里的继承的Activity 的类,我们知道,我们要捕捉key实现,只要写public boolean onKeyDown就可以了。就是这样叫到了这个函数,因为Activity类实现了class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks
这个过程就很明朗了。呵呵。
阅读(3352) | 评论(1) | 转发(0) |