Input Event Detect and Dispatch
2012-07-06 00:00
113 查看
Input Event Detect and Dispatch
2009-09-11 14:28:52| 分类: Android|字号 订阅The input event dispatch engine is in WindowManagerService.java. WindowManagerService.java creates a thread to read input event from KeyInputQueue.java and dispatches the event to the window which has current focus through binder.
// Retrieve next event, waiting only as long as the next
// repeat timeout. If the configuration has changed, then
// don't wait at all -- we'll report the change as soon as
// we have processed all events.
QueuedEvent ev = mQueue.getEvent(
(int)((!configChanged && curTime < nextKeyTime)
? (nextKeyTime-curTime) : 0));
If an input event is read, it judges the input event type. Currently support three input event types: key, trackball and pointer. Then according to event type call corresponding dispatch function to the window which has current focus through binder. For example, for key event, it calls the following code.
focus.mClient.dispatchKey(event);
At the lowest level, Android reads the real input event (keyboard, mouse or touch) from Linux input device. The corresponding source code is EventHub.cpp. For key input event, Android maps scan code to key code according to a key layout map file. OEM needs customize the key layout map file to match the needs of his own device. It uses the following method to find out the key layout map file.
// a more descriptive name
ioctl(mFDs[mFDCount].fd, EVIOCGNAME(sizeof(devname)-1), devname);
devname[sizeof(devname)-1] = 0;
device->name = devname;
// replace all the spaces with underscores
strcpy(tmpfn, devname);
for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
*p = '_';
// find the .kl file we need for this device
const char* root = getenv("ANDROID_ROOT");
snprintf(keylayoutFilename, sizeof(keylayoutFilename),
"%s/usr/keylayout/%s.kl", root, tmpfn);
bool defaultKeymap = false;
if (access(keylayoutFilename, R_OK)) {
snprintf(keylayoutFilename, sizeof(keylayoutFilename),
"%s/usr/keylayout/%s", root, "qwerty.kl");
defaultKeymap = true;
}
device->layoutMap->load(keylayoutFilename);
OEM can get the key layout map file name during Android booting, because Android will log the name. The JAVA layer wrapper is KeyInputQueue.java which is used by WindowManagerService.java. It calls EventHub.cpp through JNI. com_android_server_KeyInputQueue.cpp is the JNI implementation.
Input Event Processing
When an activity is to be launched, ActivityManagerService.java calls ActivityThread.java for creating the activity.activity.attach(appContext, this, getInstrumentation(), r.token, app,
r.intent, r.activityInfo, title, r.parent, r.embeddedID,
r.lastNonConfigurationInstance, config);
Then Activity.java creates a PhoneWindow.java instance to represent the activity. Each PhoneWindow.java contains a DecorView.java instance as the root of any views in the activity.
mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
After an activity is created, ActivityManagerService.java calls ActivityThread.java for resume the activity. At this time, ActivityThread.java calls WindowManagerImpl.java to add the DecorView.java instance.
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
wm.addView(decor, l);
WindowManagerImpl.java news a ViewRoot.java instance. ViewRoot.java has a static member which will be only initialized once for each process. It’s used to let WindowManagerService.java know that there is a process linked now.
if (!mInitialized) {
try {
sWindowSession = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"))
.openSession(new Binder());
mInitialized = true;
} catch (RemoteException e) {
}
}
After ViewRoot.java instance is created, WindowManagerImpl.java calls its setView API to bind the ViewRoot.java for the DecorView.java.
// do this last because it fires off messages to start doing things
root.setView(view, wparams, panelParentView);
In setView API, ViewRoot.java finally draws the DecorView.java and registers an IWindow instance to WindowManagerService.java.
res = sWindowSession.add(mWindow, attrs,
getHostVisibility(), mCoveredInsets);
After that WindowManager
4000
Service.java directly communicates (including dispatching input event) with this IWindow instance in ViewRoot.java. Then ViewRoot.java calls View.java to process input event. For example, for key event, dispatchKeyEvent API in View.java will be called.
public boolean dispatchKeyEvent(KeyEvent event) {
// If any attached key listener a first crack at the event.
//noinspection SimplifiableIfStatement
if (mOnKeyListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
&& mOnKeyListener.onKey(this, event.getKeyCode(), event)) {
return true;
}
return event.dispatch(this);
}
View.java detects if any key listener is registered for this view. If so, the key event will be handled by the key listener. Otherwise, it calls OnKeyDown/OnKeyUp as usual.
All the key listener implementations are under frameworks/base/core/java/android/text/method folder.
MultiTapKeyListener.java - if the keypad is NUMERIC keypad, this listener is used to transform digit inputs to characters.
QwertyKeyListener.java – if the keypad is QWERTY keypad, this listener is used.
相关文章推荐
- Input Event Detect and Dispatch
- Prototype and jasmine: element.dispatchEvent is not a function
- main and the GUI Event Dispatch Thread
- main and the GUI Event Dispatch Thread
- Difference between onInterceptTouchEvent and dispatchTouchEvent?
- Understanding Android Input Touch Events System Framework (dispatchTouchEvent, onInterceptTouchEvent
- view and viewgroup event dispatch
- How to detect and avoid memory and resources leaks in .NET applications
- Fragment如何调用所在Activity的dispatchTouchEvent(MotionEvent ev)函数
- dispatchEvent相关内容
- dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()的关联 (三)
- android 点击事件触发机制dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent
- Prototype 1.6.0 RC1: Changes to the Class and Event APIs, Hash rewrite, and bug fixes
- input keyevent命令
- xml无法显示(Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again la
- Linux jar 后台运行解决方案,nohup: ignoring input and redirecting stderr to stdout 解决方案
- getevent获取input上报事件
- [android] 调试linux input子系统驱动的用户空间命令 getevent/sendevent
- Libevent源码分析—event_base_dispatch()
- security information and event management 学习初探(一)