一、构架InputChannel的双通道
SmtTaskPositioner.register(display):
final InputChannel[] channels = InputChannel.openInputChannelPair(TAG);
mServerChannel = channels[0];// 服务端
mClientChannel = channels[1];// client端
1)对mServerChannel 在InputManagerSerivce中添加注册
mService.mInputManager.reigsterInputChannel(mServerChannel, null);
二、构建java层到native层的监听器
WindowPositionerEventReceiver extends BatchedInputEventReceiver extends InputEventReceiver
WindowPositionerEventReceiver构造方法
super(inputChannel, looper, choreographer);
->BatchedInputEventReceiver 的构造方法
super(input , looper);
->InputEventReceiver构造方法->nativeInit(new WeakReference<InputEventReceiver>(this) , intputChannel , mMessageQueue);->从native构建事件的监听
三、事件监听后处理
native层检测到事件然后回调到InputEventReceiver->dispatchInputEvent
->进入到具体实现的onInputEvent方法中
WindowPositionerEventReceiver.onInputEvent方法的具体分析:
// 非MotionEvent 直接不处理
if (!(event instanceof MotionEvent)
|| (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
return;
}
// 拿到位置信息
final float newX = motionEvent.getRawX();
final float newY = motionEvent.getRawY();
// 根据motionEvent.getAction的类型进行具体处理
...
// case MotionEvent.ACTION_MOVE
mTask.getDimBounds(mTmpRect);//拿到当前task的bounds
// mTmpRect.equals(mWindowDragBounds)// 比较确定是否需要调整task的bounds
if (!mTmpRect.equals(mWindowDragBounds)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"wm.TaskPositioner.resizeTask");
try {
mService.mActivityManager.resizeTask(
mTask.mTaskId, mWindowDragBounds, RESIZE_MODE_USER);
} catch (RemoteException e) {
}
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
// 事件完成, 经历过了mDragEnabled = true
// 向WindowManagerService发送广播
mService.mH.obtainMessage(H.FINISH_TASK_POSITIONING, mWin).sendToTarget();
// 等事件处理完成, 调用finishInputEvent , 送java向native层报告该次事件处理已经完成
// native接收后,继续接收后续事件,开始新一轮的事件监听和分发
finishInputEvent(event, handled);