日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

[转]Android输入法框的梳理

發(fā)布時間:2025/3/14 Android 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转]Android输入法框的梳理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文轉(zhuǎn)自:http://blog.csdn.net/a345017062/article/details/6121147

/frameworks/base/services/java/InputMethodManagerService.java

這是整個系統(tǒng)當(dāng)中,一切與輸入法有關(guān)的地方的總控制中心。它通過管理下面三個模塊來實現(xiàn)系統(tǒng)的輸入法框架。

1、/frameworks/base/services/java/WindowManagerService

負責(zé)顯示輸入法,接收用戶事件。

2、/frameworks/base/core/java/android.inputmethodservice/InputMethodService

輸入法內(nèi)部邏輯,鍵盤布局,選詞等,最終把選出的字符通過commitText提交出來。要做一個像搜狗輸入法這樣的東西的話,主要就是在這里做文章。

3、InputManager

由UI控件(View,TextView,EditText等)調(diào)用,用來操作輸入法。比如,打開,關(guān)閉,切換輸入法等。

??

下面說一下InputMethodManagerService這個控制中心是怎么樣與三個模塊交互的。

?

1、與WindowManagerSerivce的交互。

首先,InputMethodManagerService在初始化時,會調(diào)用IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE)),得到IWindowManager這個代理,然后通過IWindowManager與WindowManagerService交互。比如下面這些操作:

調(diào)用mIWindowManager.addWindowToken(mCurToken, WindowManager.LayoutParams.TYPE_INPUT_METHOD),讓W(xué)indowManagerService顯示輸入法界面。

調(diào)用mIWindowManager.removeWindowToken(mCurToken)讓輸入法界面關(guān)閉。

調(diào)用mIWindowManager.inputMethodClientHasFocus(client)判斷輸入法是否聚焦。

?

2、與InputMethodService的交互。

InputMethodManagerService在內(nèi)部維護著一個ArrayList<InputMethodInfo> mMethodList。這個列表會在服務(wù)啟動時通過PackageManager查詢當(dāng)前系統(tǒng)中的輸入法程序來得到。與之對應(yīng)的,每一個輸入法程序的AndroidManifest.xml中都會有一個Service,而每個Service中都會有標(biāo)記來告訴系統(tǒng),自己是個輸入法程序。下面這個是我從系統(tǒng)自帶的例子Samples/SoftKeyboard/AndroidManifest.xml中的取出來的:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"?

?? ? ? ?package="com.example.android.softkeyboard">

?? ?<application android:label="@string/ime_name">

?? ? ? ?<service android:name="SoftKeyboard"

?? ? ? ? ? ? ? ?android:permission="android.permission.BIND_INPUT_METHOD">

?? ? ? ? ? ?<intent-filter>

?? ? ? ? ? ? ? ?<action android:name="android.view.InputMethod" />

?? ? ? ? ? ?</intent-filter>

?? ? ? ? ? ?<meta-data android:name="android.view.im" android:resource="@xml/method" />

?? ? ? ?</service>

?? ?</application>

</manifest>

另外,InputMethodManagerService內(nèi)部還有一個PackageReceiver,當(dāng)系統(tǒng)中有程序的安裝、刪除、重啟等事件發(fā)生時,會更新mMethodList。InputMethodManagerService打開,關(guān)閉,切換輸入法時,其實就是在操作mMethodList中某個InputMethodInfo。把InputMethodInfo中的代表某個輸入法的InputMethodService啟動或者銷毀,就實現(xiàn)了輸入法的打開和關(guān)閉。

?

3、與InputMethodManager的交互

InputMethodManager中會包含一個IInputMethodManager,這個東西就是InputMethodManagerService的代理,打開關(guān)閉輸入法這些操作就是由InputMethodManager中的某些方法調(diào)用IInputMethodManager中相應(yīng)的方法來實現(xiàn)的。比如:

mService.getInputMethodList()獲取輸入法列表。

mService.updateStatusIcon(imeToken, packageName, iconId)更新輸入法圖標(biāo),即屏幕上方狀態(tài)欄中的輸入法圖標(biāo)。

mService.finishInput(mClient)隱藏當(dāng)前輸入法。這所以不說關(guān)閉輸入法,是因為輸入法服務(wù)啟動起來以后,只有在系統(tǒng)關(guān)閉或者切換輸入法時才會關(guān)閉。

mService.showSoftInput(mClient, flags, resultReceiver)打開當(dāng)前輸入法。

...

??

分別介紹完三大模塊之后,再介紹兩個東西,輸入法的實現(xiàn)和怎么樣調(diào)用輸入法。

?

1、以系統(tǒng)的SoftKeyboard為例,實現(xiàn)一個輸入法至少需要Keyboard,KeyboardView,CandidateView,SoftKeyboard這四個東西。

CandidateView負責(zé)顯示軟鍵盤上面的那個候選區(qū)域。

Keyboard負責(zé)解析并保存鍵盤布局,并提供選詞算法,供程序運行當(dāng)中使用。其中鍵盤布局是以XML文件存放在資源當(dāng)中的。比如我們在漢字輸入法下,按下b、a兩個字母。Keyboard就負責(zé)把這兩個字母變成爸、把、巴等顯示在CandidateView上。

KeyboardView負責(zé)顯示,就是我們看到的按鍵。

上面這兩人東西合起來,組成了InputView,就是我們看到的軟鍵盤。

SoftKeyboard繼承了InputMethodService,啟動一個輸入法,其實就是啟動一個InputMethodService,當(dāng)SoftKeyboard輸入法被使用時,啟動就會啟動SoftKeyboard這個Service。InputMethodService中管理著一個繼承自Dialog的SoftInputWindow,而SoftInputWindow里面就包括了InputView和CandidateView這兩個東西。

?

2、怎么樣調(diào)用輸入法呢?

說起這個東西,很自然地想起EditText來,我們團隊跟蹤過這個Widget,EditText本身很簡單,主要的代碼在TextView和View當(dāng)中。這兩個Widget本身又很復(fù)雜,雜在一起說不清楚。這里我就把我們團隊以前做過的一個小例子拿進來做參考,說明一下如何從一個View上調(diào)用輸入法和如何接收輸入法傳過來的字符串。

小例子的起源來自于我們要做一個瀏覽器,需要在SurfaceView來在Canvas上面繪制自己需要的東西,開啟自己的主控制循環(huán)線程,事件處理等。比如我要在SurfaceView上繪制輸入瀏覽器中的按鈕、文本、圖片、輸入框等,當(dāng)然這些和ImageView,TextView沒有關(guān)系,都是用自己的UI引擎來做的。最后所有問題都解決了,卻在輸入框上卡殼了。因為要實現(xiàn)輸入,得調(diào)用EditText,否則就必須自己去和EditText一樣連接輸入法。以前找過相關(guān)資料,看網(wǎng)上也有人碰到過這個問題,但都沒有答案。最后,還是團隊中一個很牛的娃給解決了。代碼很簡單,不出二十行,但沒資料,View的源碼又太龐大,費的勁卻是只有我們團隊的人才能體會得到的。。。這里佩服張老二同學(xué)一下,沒有他的努力,就沒有下面這二十多行很重要很重要的源碼的誕生。

首先,定義一個繼承自BaseInputConnection的類。

public class MyBaseInputConnection extends BaseInputConnection{

public MyBaseInputConnection(View targetView, boolean fullEditor) {

super(targetView, fullEditor);

}

public static String tx="";

@Override

public boolean commitText(CharSequence text, int newCursorPosition) {//輸入法程序就是通過調(diào)用這個方法把最終結(jié)果輸出來的。

tx = text.toString();

return true;

}

}

BaseInputConnection相當(dāng)于一個InputMethodService和View之間的一個通道。每當(dāng)InputMethodService產(chǎn)生一個結(jié)果時,都會調(diào)用BaseInputConnection的commitText方法,把結(jié)果傳遞出來。

public class MyView extends SurfaceView ...{

InputMethodManager input = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);//得到InputMethodManager。

ResultReceiver receiver = new ResultReceiver(new Handler() {//定義事件處理器。

public void handleMessage(Message msg) {

?

}

});

... ...

input.showSoftInput(this, 0, mRR);//在你想呼出輸入法的時候,調(diào)用這一句。

... ...

@Override

public InputConnection onCreateInputConnection(EditorInfo outAttrs) {//這個方法繼承自View。把自定義的BaseInputConnection通道傳遞給InputMethodService。

return new MyBaseInputConnection(this, false);

}

}

低級界面上面,自己調(diào)用輸入法并接收輸入法的輸出結(jié)果,就是這樣的。

下面我想提一下和這個話題相關(guān)的另外一件事,就是前面解決過的一個Bug:

http://blog.csdn.net/a345017062/archive/2011/01/04/6116305.aspx

通過這個問題,可以看出WebView上面的輸入法是如何實現(xiàn)的。簡單來說,WebView就是一個ViewGroup,它里面有兩層,上層是一個EditText,下層是瀏覽器頁面。當(dāng)瀏覽器的輸入框被用戶點中,需要顯示輸入法時,就把上層EditText的位置移到瀏覽器的輸入框的位置,高速好EditText的大小和樣式后,讓EditText和瀏覽器頁面融為一體,效果就很好了。

通常來說,這個方式應(yīng)該比自己調(diào)用輸入法要好些??梢陨僮龊芏嗍?。不過,如果產(chǎn)品經(jīng)理是個很有想像力的人的話,你就不能滿足他設(shè)計出來的有可能極端變態(tài)卻非常炫的輸入效果了。

轉(zhuǎn)載于:https://www.cnblogs.com/freeliver54/archive/2011/09/08/2171339.html

總結(jié)

以上是生活随笔為你收集整理的[转]Android输入法框的梳理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。