android輸入法機制的學習總結(未完待續)

sunhang發表於2019-01-28

android輸入法機制包含三部分:1,輸入法服務(InputMethodService),簡稱IMS;2,輸入法系統服務(InputMethodManagerService),簡稱IMMS;3,客戶端app(即當前要輸入內容的app);

在分析的時候我先把一些類或介面先列出來

IMS一端

類的關係

我先把類列出來

  1. InputMethodService;
  2. IInputMethodWrapper;
  3. InputMethod <
    |– AbstractInputMethodImpl <
    |– InputMethodImpl;
  4. InputConnectionWrapper(它實現了InputConnection介面);
  5. InputContextCallback;

這些類的關係是什麼呢,於是根據程式碼畫了一張UML圖

android輸入法機制的學習總結(未完待續)

概括說,service通過onBind()返回一個繼承了Stub的IInputMethodWrapper物件,InputMethodWrapper內部弱引用了一個InputMethodImpl物件。那麼InputConnectionWrapper物件是如何被最終傳遞給service的呢。於是我畫了一個時序圖,如下。

android輸入法機制的學習總結(未完待續)

遠端IPC呼叫IInputMethodWrapper的startInput方法,把IInputContext引用的物件傳遞過來,通過時序圖可以看到InputMethodService是如何得到InputConnectionWrapper物件的,從而間接地可以得到IInputContext引用的物件(InputConnectionWrapper內聚了IInputContext)。這就賦予了servie遠端和第三方app客戶端通訊的能力。這個IInputContext提供了什麼介面,service就可以和客戶端做什麼通訊。比如它有個void commitText(CharSequence text, int newCursorPosition);
介面,可以使得service提交文字到客戶端相應的EditText中。

注意,這裡的IInputMethodWrapper是繼承了IInputMethod.Stub,所以它 is-a Binder,實現了aidl定義的介面IInputMethod,而不是InputMethod。 這個容易迷惑人,InputMethod不是aidl定義的。

客戶端

  1. IInputConnectionWrapper;
  2. ControlledInputConnectionWrapper;

IInputConnectionWrapper相關的類的關係如下

android輸入法機制的學習總結(未完待續)

在客戶端的InputMethodManager的startInputInner方法中,建立了ControlledInputConnectionWrapper物件,並把它作為引數呼叫IInputMethodManager的startInputOrWindowGainedFocus。IInputMethodManager正是IMMS對應的binder,這樣就通過IMMS把ControlledInputConnectionWrapper對應的binder傳遞給了IMS端。

不難想象,這裡的ControlledInputConnectionWrapper所對應的service端的正是InputConnectionWrapper裡邊的IInputContext。

android輸入法機制的學習總結(未完待續)

系統服務端

InputMethodManagerService

IMS端和客戶端共用:InputConnection

需要用到的aidl

  1. IInputContextCallback.aidl
  2. IInputContext.aidl
  3. InputBinding.aidl
  4. IInputMethod.aidl
  5. IInputMethodManager.aidl
  6. IInputMethodClient.aidl

來源:https://juejin.im/post/5c4ea6fcf265da616624d4d9

相關文章