本系列的上一篇文章《Monkey源碼分析之事件源》中我們描述了monkey是怎么從事件源取得命令,然后將命令轉換成事件放到事件隊列里面的,但是到現在位置我們還沒有了解monkey里面的事件是怎么一回事,本篇文章就以這個問題作為切入點,嘗試去搞清楚monkey的event架構是怎么樣的,然后為什么是這樣架構的,以及它又是怎么注入事件來觸發點擊等動作的。
在看這篇文章之前,希望大家最好先去看下另外幾篇博文,這樣理解起來就會更容易更清晰了:
public class MonkeyKeyEvent extends MonkeyEvent { private long mDownTime = -1; private int mMetaState = -1; private int mAction = -1; private int mKeyCode = -1; private int mScancode = -1; private int mRepeatCount = -1; private int mDeviceId = -1; private long mEventTime = -1; private KeyEvent keyEvent = null; public MonkeyKeyEvent(int action, int keycode) { super(EVENT_TYPE_KEY); mAction = action; mKeyCode = keycode; } public MonkeyKeyEvent(KeyEvent e) { super(EVENT_TYPE_KEY); keyEvent = e; } public MonkeyKeyEvent(long downTime, long eventTime, int action, int code, int repeat, int metaState, int device, int scancode) { super(EVENT_TYPE_KEY); mAction = action; mKeyCode = code; mMetaState = metaState; mScancode = scancode; mRepeatCount = repeat; mDeviceId = device; mDownTime = downTime; mEventTime = eventTime; }MonkeyKeyEvent有多個構造函數,參數都不一樣,但是目的都只有一個,通過傳進來的參數獲得足夠的信息保存成成員變量,以便今后創建一個android.view.KeyEvent,皆因該系統事件就是可以根據不同的參數進行初始化的。比如下面的getEvent方法就是根據不同的參數創建對應的KeyEvent的。注意這系統KeyEvent是非常重要的,因為我們今后通過WindowManager注入事件就要把它的對象傳進去去驅動相應的按鍵相關的事件。
* @return the key event */ private KeyEvent getEvent() { if (keyEvent == null) { if (mDeviceId < 0) { keyEvent = new KeyEvent(mAction, mKeyCode); } else { // for scripts keyEvent = new KeyEvent(mDownTime, mEventTime, mAction, mKeyCode, mRepeatCount, mMetaState, mDeviceId, mScancode); } } return keyEvent; }支持的成員變量比較多,名字都挺淺顯易懂,我這里就簡單描述兩個我們最常用的:
public static final int KEYCODE_MENU = 82;
private int run(String[] args) { ... if (!getSystemInterfaces()) { return -3; } .... }那么我們進入該方法看下我們需要的WindowManager是怎么初始化的。
private boolean getSystemInterfaces() { mAm = ActivityManagerNative.getDefault(); if (mAm == null) { System.err.println("** Error: Unable to connect to activity manager; is the system " + "running?"); return false; } mWm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); if (mWm == null) { System.err.println("** Error: Unable to connect to window manager; is the system " + "running?"); return false; } mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); if (mPm == null) { System.err.println("** Error: Unable to connect to package manager; is the system " + "running?"); return false; } try { mAm.setActivityController(new ActivityController()); mNetworkMonitor.register(mAm); } catch (RemoteException e) { System.err.println("** Failed talking with activity manager!"); return false; } return true; }
@Override public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) { if (verbose > 1) { String note; if (mAction == KeyEvent.ACTION_UP) { note = "ACTION_UP"; } else { note = "ACTION_DOWN"; } try { System.out.println(":Sending Key (" + note + "): " + mKeyCode + " // " + MonkeySourceRandom.getKeyName(mKeyCode)); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(":Sending Key (" + note + "): " + mKeyCode + " // Unknown key event"); } } // inject key event try { if (!iwm.injectKeyEvent(getEvent(), false)) { return MonkeyEvent.INJECT_FAIL; } } catch (RemoteException ex) { return MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION; } return MonkeyEvent.INJECT_SUCCESS; }注意傳入參數
@Override public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) { if (verbose > 1) { System.out.println("Sleeping for " + mThrottle + " milliseconds"); } try { Thread.sleep(mThrottle); } catch (InterruptedException e1) { System.out.println("** Monkey interrupted in sleep."); return MonkeyEvent.INJECT_FAIL; } return MonkeyEvent.INJECT_SUCCESS; }所以雖然不同的MonkeyEvent實現類都實現了父類的injectEvent方法,但是并不是所有的的MonkeyEvent都需要注入事件的。所有這個接口方法的名字我覺得Google 工程師起得不好,比如叫做handleEvent就不會造成混亂了(個人見解)
事件處理方式 | MonkeyEvent實現類 | 關鍵代碼 | 注釋 |
通過WindowManager注入事件 | MonkeyKeyEvent | injectKeyiwm.injectKeyEvent(getEvent(),false)Event | |
MonkeyTouchEvent | iwm.injectPointerEvent(me,false) | | |
MonkeyTrackballEvent | iwm.injectTrackballEvent(me,false) | | |
通過往事件設備/dev/input/event0發送命令注入事件 | MonkeyFlipEvent | FileOutputStream("/dev/input/event0") | |
通過ActvityManager的startInstrumentation方法啟動一個應用 | MonkeyInstrumentationEvent | iam.startInstrumentation(cn,null, 0,args,null) | |
睡眠 | MonkeyThrottleEvent | Thread.sleep(mThrottle) | |
MonkeyWaitEvent | Thread.sleep(mWaitTime) | |
作者 | 自主博客 | 微信 | CSDN |
天地會珠海分舵 | http://techgogogo.com | 服務號:TechGoGoGo 掃描碼: | 向AI問一下細節 免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。 猜你喜歡最新資訊相關推薦相關標簽AI
助 手
亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女
|