編輯:關於Android編程
Android輸入法框架(Input Method Framework,IMF)是Android中非常重要的模塊,它分布於三個部分(確切的說,是三個進程),
包含編輯框的客戶(Client)app,表示普通的使用輸入法的app進程。當點擊編輯框時,會切換出當前選中的輸入法;當用戶在輸入法輸入字符,提交候選詞,則會更新到編輯框中。為了完成這些行為,它需要跟下面的兩個輸入法相關服務進行交互。對於普通app開發者而言,他們一般使用系統提供的EditText,該類和其父類TextView已經很好的封裝了跟輸入法服務之間的交互;如果是自定義的編輯框,則需要自己處理這種交互。輸入法(input method,IME)服務(service),是具體的輸入法進程,例如自帶的拉丁輸入法或者谷歌,搜狗等拼音輸入法。它們一般提供一個輸入窗口,可以根據用戶的要求打開或者關閉;可以把用戶輸入的字符和提交的候選詞更新給client等等。這是一個用戶級別的Service。為了方便開發者編寫新的輸入法,IMF提供了抽象基類InputMethodService供輸入法開發者擴展。輸入法管理者(Input method manager,IMM)服務(Service),這是一個Android系統級的服務,用於管理多個輸入法以及同其他系統服務(例如window manager service)進行交互。這部分代碼是app開發者和IME開發者都不需要關心的。為了方便描述,後文分別稱該三個組件為:client,IME和IMM。
這三個部分需用共同合作才能完成輸入法的工作。例如打開一個app,並且一個edit框獲取了focus焦點。此時client會通知IMM打開輸入法,然後IMM查看當前選中的IME,並調用該IME的start操作。這個簡單的開始操作需要三個組件的配合。再比如用戶提交了候選詞,此時IME需要將候選詞告訴client。這裡須要IME和client的合作。
因為這三個部分是三個進程,所以它們之間必須通過IPC進行通訊。在Android中,IPC機制是通過binder機制和aidl接口進行通信的。
對於Client而言,它提供了兩個接口IInputMethodClient.aidl和IInputContext.aidl。前者是供IMM調用的,後者是供IME調用的。IMM提供了接口IInputMethodManager.aidl供其他兩個組件調用。IME提供了兩個接口IInputMethod.aidl和IInputMethodSession.aidl,前者供IMM調用,後者供client直接調用。這些調用關系可以參考下圖:
這些接口定義都在java/com/android/internal/view目錄下。那這些接口是如何實現的呢?
先看client提供的接口。IInputContext是由同一目錄下的IInputConnectionWrapper實現的。正如名字所說,它只是一個wrapper,它把接收到的IPC消息委托給你InputConnection的一個實現。例如對於EditText而言,實現是EditableInputConneciton。
在調用方,IME也不是直接操作IInputContext接口。它會調用實現了InputConnection接口的InputConnectionWrapper(也在前面目錄下)。該對象封裝了從client傳過來的IInputContext實例。
對於IME對client的調用操作,它會經歷下面流程(以調用commitText為例,它表示提交候選詞):
在IME看來,接口是InputConnection;在client上,實現的也是InputConnection。IInputContext完全被隱藏起來了。所以Android官方文檔說IME通過InputConnection接口來操作client。
再看client提供的另外一個接口IInputMethodClient,IMM是直接調用的。IMM的代碼就是InputMethodManagerService。在client端,InputMethodManager類中有一個對IInputMethodClient.stub的實現。
對IMM提供的IInputMethodManager接口而言,它是由InputMethodManagerService來實現的。在client端,InputMethodManager的getInstance(是個singleton)會調用ServiceManager.getService(Context.INPUT_METHOD_SERVICE)獲取該接口,然後創建InputMethodManager。所以對於client而言,它跟IMM的交互都是通過InputMethodManager來封裝完成的,並不需要關心IInputMethodManager接口。對於IME,如果它想操作IMM,也同樣通過InputMethodManager。
下面是IME提供的接口。類似於使用InputConnection封裝IInputContext,有兩個接口InputMethod和InputMethodSession分別對應著了IInputMethod和IInputSession。
對於InputMethod,IInputMethodWrapper實現了IInputMethod.stub。對於收的的IPC請求,都轉發給InputMethod實例。一般而言,這個實例是InputMethodService中定義的InputMethodImpl。該實例是InputMethodService的內部類,所以可以操作InputMethodService。對於其客戶IMM,InputMethodManagerService會直接調用IInputMethod的方法發起IPC請求。
對於InputMethodSessoin,非常類似,IInputMethodSessionWrapper實現了IInputMethodSession.stub。同樣在InputMethodService中有InputMethodSessionImpl實現了InputMethodSession接口,有一個該類型的對象在IInputMethodSessionWrapper中,負責具體處理過來的IPC消息。在client端,InputMethodManager有一個IInputMethodSession
mCurMethod對象。開發者只需要調用InputMethodManager,而由InputMethodManager調用IInputMethodSession的IPC操作。
總結一下,無論是client還是IME的開發者,都不需要直接操作aidl接口。在client端,對於IMM和IME的操作都是通過InputMethodManager發起的,用戶甚至不用關心這些IPC操作是發給誰的;在IME端,開發者通過InputConnection給client發IPC消息,通過InputMethodManager給IMM發。而在IMM端,雖然是直接操作aidl接口的stub對象,但因為一般開發者不需要改寫它,所以也無關緊要。通過這種方式,簡化了開發者的跨進程操作。
最後再總結下代碼位置:
所有的aidl接口都在java/com/android/internal/view目錄下。它只是internal可見,所以普通開發者無法直接訪問它。用戶可以訪問的接口或類,包括InputConnection,InputMethodManager,InputMethod,InputMethodSession都在java/android/view/inputmethod目錄下。java/com/android/internal/view還包含IInputConnecitonWrapper,InputConnectionWrapper。java/android/view/inputmethod還包含BaseInputConnectionjava/android/inputmethodservice包含IME端相關代碼,例如IInputMethodWrapper,IInputMethodSessionWrapper,InputMethodImpl,InputMethodSessionImpl,InputMethodService。IMM的InputMethodManagerService在services/java/com/android/server下。代碼主要就是這四個目錄。
前言 在Android應用中,經常有場景會需要使用到設備上存儲的圖片,而直接從路徑中獲取無疑是非常不便利的。所以一般推薦調用系統的Gallery應用,選擇圖片,然後使用
本文實例講解了Android實現圖片文字輪播特效的詳細代碼,分享給大家供大家參考,具體內容如下圖片輪播是類似知乎日報上的一個輪播效果,如下圖。好了直接進入正題,首先是出示
先來看看效果圖跳動的小球做這個動畫,需掌握: 1、屬性動畫 2、Path類
微信群是我們經常聊天聊工作的地方,但是你需要離開的時候想要將這個微信群轉給一個人來管理該怎麼辦呢?那麼微信群怎麼轉讓群主呢?微信群怎麼轉讓給別人?微信群怎麼