使用Instrumentation發送事件時發現每次都要幾十毫秒,原因是它使用的模式是InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH(2),而不是INJECT_INPUT_EVENT_MODE_ASYNC(0)。
public void sendPointerSync(MotionEvent event) {
validateNotAppThread();
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
}
try {
WindowManagerGlobal.getWindowManagerService().injectInputAfterTransactionsApplied(event,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
} catch (RemoteException e) {
}
}
要想異步發送事件,可以通過反射調用InputManager.getInstance().injectInputEvent()。
public class XXXUtil {
private static InputManager sInputManager;
private static Method sInjectInputEventMethod;
public static InputManager getInputManager() {
if (sInputManager == null) {
try{
Class<?> inputManagerClass=InputManager.class;
Method getInstanceMethod = inputManagerClass.getMethod("getInstance");
sInputManager = (InputManager)getInstanceMethod.invoke(inputManagerClass);
}catch (Exception e){
}
}
return sInputManager;
}
public static Method getInjectInputEventMethod() {
if (sInjectInputEventMethod == null) {
try{
Class<?> inputManagerClass=InputManager.class;
sInjectInputEventMethod = inputManagerClass.getMethod("injectInputEvent", InputEvent.class, int.class);
}catch (Exception e){
}
}
return sInjectInputEventMethod;
}
private static void sendPointerEvent(MotionEvent event) {
try {
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
}
getInjectInputEventMethod().invoke(getInputManager(), event, 0);
} catch (Exception e) {
}
}
private static void sendKeyEvent(KeyEvent event) {
long downTime = event.getDownTime();
long eventTime = event.getEventTime();
int action = event.getAction();
int code = event.getKeyCode();
int repeatCount = event.getRepeatCount();
int metaState = event.getMetaState();
int deviceId = event.getDeviceId();
int scancode = event.getScanCode();
int source = event.getSource();
int flags = event.getFlags();
if (source == InputDevice.SOURCE_UNKNOWN) {
source = InputDevice.SOURCE_KEYBOARD;
}
if (eventTime == 0) {
eventTime = SystemClock.uptimeMillis();
}
if (downTime == 0) {
downTime = eventTime;
}
KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
try {
getInjectInputEventMethod().invoke(getInputManager(), newEvent, 0);
}catch (Exception e){
}
}
}