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 WindowManagerService.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.
分享到:
相关推荐
### Android之ANR的原理(Input, Service, Broadcast) #### ANR概述 ANR(Application Not Responding)是指Android应用程序在执行过程中响应超时的一种异常状态。当应用程序长时间不响应用户的操作时,系统会提示...
分析ANR的过程通常涉及查看系统日志,例如在上述示例中,可以看到输入事件调度超时(Input event dispatching timed out),以及ANR的具体原因(keyDispatchingTimedOut)。此外,系统还会记录ANR发生的时间和生成的...
事件可以沿着事件分发链(Event Dispatching Chain)传递,直至被消费。 6. **动画(Animations)**:Android提供了多种动画类型,如属性动画(Property Animation)、视图动画(View Animation)和过渡动画...
主要分为四类:InputDispatching Timeout、BroadcastQueue Timeout、Service Timeout和ContentProvider Timeout。避免ANR的关键在于避免在主线程(UI线程)执行耗时操作,耗时任务应放在子线程中执行。通过Logcat...
3. **事件传递机制(Event Dispatching)**:Android事件系统遵循“冒泡”机制,事件从最底层的视图开始,逐级向上层视图传递,直到被某个视图消费或者到达根视图。通过return true在事件处理方法中,可以阻止事件...
3. **事件处理机制**:事件分发链(Event Dispatching)是Android中重要的一环,源码可能会展示触摸事件的处理流程,帮助理解如何正确处理点击事件和滑动事件。 4. **数据存储**:Android提供了SQLite数据库、...
首先,Android事件处理主要依赖于事件传递链(Event Dispatching Chain)。当用户在屏幕上进行操作时,比如点击或滑动,这些动作会被转换为事件对象,如MotionEvent或KeyEvent。事件首先由WindowManager服务捕获,...
理解事件传递机制(Event Dispatching)和如何使用`OnClickListener`、`OnTouchListener`接口是Android UI交互的基础。 2. **EX06_13**:可能涉及Android的多线程编程,例如使用`AsyncTask`进行后台任务处理。在...
在Android中,用户对UI的操作(如点击按钮)会触发一系列的事件,这些事件会通过事件传递链(Event Dispatching Chain)从视图树(View Hierarchy)顶部向下传递。默认情况下,如果用户在短时间内连续点击,系统可能...
在这一章节,还可能涵盖了Android的事件传递机制,即事件冒泡(Event Propagation)和事件分发(Event Dispatching)。源码会展示如何捕获和处理点击事件,以及如何在复杂的视图层次结构中控制事件流。同时,这一章...
5. **事件分发(Event Dispatching)**:当用户点击某个菜单项时,需要将事件分发到相应的菜单项上,以便执行相应功能。这涉及到事件的传递机制和onClickListener的设置。 6. **项目结构与模块化**:一个完整的...
4. **事件分发(Event Dispatching)** - 触摸事件在Android中的处理涉及事件的传递和分发机制,从顶级的ViewGroup开始,沿着View层次结构向下传递,直到某个View消费掉事件。 5. **动画(Animation)** - Android...
8. **事件分发(Event Dispatching)**:理解事件传递机制,确保滑轮关节在接收到触摸事件后能正确响应。 9. **适配器(Adapter)**:如果滑轮关节用于展示数据列表,可能需要使用Adapter来绑定数据到视图。 10. *...
5. **事件调度(Event Dispatching)**:事件调度器接收事件,根据注册信息将事件分发到相应的事件处理器。 在实际应用中,事件机制常被用于构建用户界面(UI)框架,如Java的Swing和JavaFX,或者JavaScript中的DOM...
3. **触摸事件分发(MotionEvent Dispatching)**: 触摸事件(MotionEvent)在Android中由dispatchTouchEvent()、onTouchEvent()和onInterceptTouchEvent()三个方法共同处理。dispatchTouchEvent()用于事件的初始...
1. 出租车调度方法:TESLA(centralized taxi dispatching with global fairness),即一种集中式出租车调度方法,旨在通过实时匹配出租车与乘客来提升司机的收入效率,同时解决司机收入公平性问题。 2. 传统出租车...
Android事件处理基于一个称为“事件传递链”(Event Dispatching Chain)的机制。当用户在屏幕上进行操作时,事件会沿着View层次结构从父View到子View依次传递,直到被某个View消费。这一过程称为事件分发。 2. **...
这个是用支持向量机求解AGVs调度的python代码,需要的可以拿去,有研究车间调度和AGV调度或者两者集成调度的可以参考。
通过MATLAB,使用粒子群算法(PSO)实现电力系统的经济调度。调度代码清晰,适合做电力系统经济调度的相关学习