摘要:介紹了Android系統(tǒng)的基本概念,并分析了Android特性和迅速流行的原因。講解了Android系統(tǒng)提供的輸入法框架,實現(xiàn)一個輸入法所需要做的工作,和現(xiàn)有輸入法設(shè)計的局限性。然后介紹插件式程序設(shè)計的實現(xiàn)方法,并對手機等數(shù)碼產(chǎn)品中插件式安裝程序的優(yōu)點進行分析,并采用該方法設(shè)計了包含主程序,和兩個插件方式安裝的輸入法程序。
關(guān)鍵詞:android系統(tǒng);輸入法;插件式程序;手機應(yīng)用
中圖分類號:TP399 文獻標(biāo)識碼:A文章編號:1009-3044(2009)35-9979-03
Android Plug-in Input Method Programs Design
LI Ping-xin
(School of Software Engineering Tongji University, Shanghai 200433, China)
Abstract: Introduced the basic concept of Android system, and analyzes the characteristics of Android and the reasons for Android been growing in popularity. Explained the Android system input method framework, how to implements an input method, and the limitations of the current input method designing. Then introduced the plug-in program implementations. As well as mobile phones and other digital products, the advantages and disadvantages of plug-in program analysis. And using the method designed a Input method application including main program Pinyin input method and Handwriting input method.
Key words: android; inputmethod; plus; mobile application
1 背景
1.1 Android系統(tǒng)介紹
Android是Google開發(fā)的基于Linux平臺的開源手機操作系統(tǒng)。它包括操作系統(tǒng)、用戶界面和應(yīng)用程序—— 移動電話工作所需的全部軟件,而且不存在任何以往阻礙移動產(chǎn)業(yè)創(chuàng)新的專利障礙。Android SDK的提供了一些使用JAVA語言開發(fā)Android平臺應(yīng)用所必須的工具和API,同時還提供了使用C/C++語言開發(fā)的NDK工具[1]。
Android包含了一整套核心庫。它為java語言提供了很多有用的功能。在Android系統(tǒng)中所有的應(yīng)用都運行在它自己的進程里,該進程是一個Dalvik虛擬機的實例。Dalvik被設(shè)計成能在一臺設(shè)備上高效的運行多個虛擬機實例。Dalvik虛擬機的可執(zhí)行文件被封裝成Dalvik可執(zhí)行格式(.dex)。這是被優(yōu)化過的最小內(nèi)存依賴的格式。java編譯器(dx工具)將注冊了的 和運行時用到的類編譯成.dex格式。Dalvik虛擬機依賴于底層linux內(nèi)核提供的功能,如線程機制,和內(nèi)存管理機制。
Android程序通過apk文件進程安裝。apk格式是一種壓縮格式,apk文件內(nèi)包含程序執(zhí)行的dex代碼和程序使用的圖片,音頻,界面布局文件,C/C++靜態(tài)庫等資源文件。
1.2 Android系統(tǒng)特性
Android系統(tǒng)是開放源代碼項目,整個系統(tǒng)的代碼都是免費開放的。Android系統(tǒng)的開發(fā)語言是Java(因為該語言沒有通過Sun的認(rèn)證,嚴(yán)格來說不能算作是Java語言,而是類Java語法的語言),java作為最流行的面向?qū)ο蟮恼Z言,不僅容易學(xué)習(xí),豐富的api更加容易開發(fā)高級應(yīng)用程序。并且傳統(tǒng)的手機應(yīng)用程序,主要是采用J2ME平臺,J2ME是采用Java作為開發(fā)語言,開發(fā)語言上的親緣關(guān)系,使現(xiàn)有的J2ME手機應(yīng)用程序很容易的移植到Android中。同時Android系統(tǒng)是基于Linux系統(tǒng)的,Linux系統(tǒng)中包含了大量的開源應(yīng)用庫,使用Android系統(tǒng)的NDK,更可以方便的使用現(xiàn)有Linux庫開發(fā)出豐富的應(yīng)用程序[2]。基于以上特性,Android系統(tǒng)已經(jīng)推出,經(jīng)歷了一年時間后,被各大手廠商接受,并迅速流行。
2 輸入法框架介紹
輸入法是介于用戶,應(yīng)用程序文本編輯框之間的聯(lián)系通道。輸入法模塊一般提供一個輸入面板如軟鍵盤,觸摸板,將用戶的輸入根據(jù)某種輸入算法(如筆畫輸入,拼音輸入,手寫輸入等算法)轉(zhuǎn)換成詞組傳遞給文字輸入框組件。Android 系統(tǒng)在1.5版本后開始提供輸入法框架。該框架提供了InputMethodManager服務(wù)組件來管理系統(tǒng)中安裝的各種的輸入法,InputMethodService是代表某個具體輸入法的進程,他負(fù)責(zé)某個輸入法的初始化、創(chuàng)建、運行和銷毀。InputConnection是負(fù)責(zé)應(yīng)用程序文字輸入框和輸入法交換數(shù)據(jù)。輸入法框架如圖1所示。
目前Android系統(tǒng)的輸入法框架比較完善,實現(xiàn)一個輸入法,只需要繼承InputMehodService,并實現(xiàn)該類中定義的方法,和輸入法輸入邏輯和具體算法引擎,和軟鍵盤布局,候選字顯示等。
3 插件式輸入法的必要性和插件式程序的實現(xiàn)原理
目前比較流行的手機輸入方式有全鍵盤拼音/英文輸入,九鍵盤拼音/筆畫/英文/數(shù)字輸入,手寫輸入等[3]。雖然某一種輸入可以應(yīng)對大多數(shù)情況的輸入,但是多種輸入法搭配會提供輸入效率。雖然可以安裝多個不同類型輸入程序,來提供多種輸入方式,但是在Android系統(tǒng)中,多種輸入法間切換時,需要先長擊輸入框,然后在彈出的選擇框總選擇需要的輸入法,這個過程雖然只有2步操作,但是整個過程將會耗費若干秒時間,并且有些情況下,新選擇的輸入法不會立刻運行,而是要等待一段比較長的時間后才會啟動起來。這種方式將會嚴(yán)重降低用戶的輸入效率。比較普遍的做法是將多種輸入法全部放到一個安裝文件中。比如一個apk文件同時提供拼音輸入、九鍵筆畫輸入,和手寫輸入,那么這個apk文件將會占用大量的手機內(nèi)存空間,但與此同時用戶可能只習(xí)慣使用其中的少數(shù)幾種輸入法,這樣輸入法程序就浪費了一部分內(nèi)存空間,因為輸入程序的詞庫,算法引擎占用空間比較多,同時手機內(nèi)存又是比較少的。
為此如果能夠提供一種插件式輸入法安裝方式,即用戶可以選擇安裝或卸載某個輸入法,但是多個輸入法,卻是運行在一個程序中進行,并且輸入法的切換過程只需點擊一下既可快速切換[4]。
插件式輸入法將包括2部分:輸入切換器,和各種輸入法插件。輸入法切換器用于管理安裝的各種輸入法插件,和在他們之間進行快速的切換。各個輸入法插件則提供不同的輸入方式。用戶安裝輸入法,必須要安裝輸入法切換器,然后根據(jù)需要來安裝不同的輸入法插件。
Android提供了PackageManager類,可以查詢所有安裝在系統(tǒng)中apk程序信息。PathClassLoader類,用于從其他apk文件中加載類。這是插件輸入法設(shè)計的關(guān)鍵。
PackageManager的queryIntentActivities(intent, flag)方法可以查詢系統(tǒng)中所有的提供滿足參數(shù)intent(intent為“意圖”的意思,比如android中有一種“SEND”意圖,表示用來共享數(shù)據(jù),如Email程序,短信程序等都屬于這種intent,在程序的AndroidManifest.xml文件中,可以設(shè)置程序的意圖。)的所有Activity信息,包括Activity的類名稱,apk代碼路徑等[5]。
知道了插件apk路徑,就可以通過語句“new PathClassLoader(changed.sourceDir,classLoader)”來構(gòu)造一個加載插件輸入法代碼的ClassLoader。通過ClassLoader的loadClass(className)方法來加載插件類。然后調(diào)用他的構(gòu)造函數(shù),即可創(chuàng)建該類的內(nèi)存實例的對象。
Class c = classLoader.loadClass(changed.className);
c.getConstructor(args_type...).newInstance(args...);
然后就可以調(diào)用插件程序中的代碼了。
4 輸入法插件的設(shè)計
4.1 輸入法管理器設(shè)計
插件式輸入法,需要一個主程序Switcher,用于查詢、管理、加載輸入法插件和輸入法其他的一些功能,這些功能主要包括輸入候選字的顯示視圖,輸入法切換視圖等。插件式輸入法系統(tǒng)的結(jié)構(gòu)圖如圖2。
在輸入法服務(wù)進程啟動時,通過queryIntentActivities()函數(shù)查詢系統(tǒng)中的輸入法插件,為了便于查詢,需要定義一個專用的輸入法插件標(biāo)intent識符,如“com.android.lpx.INPUMETHOD_PLUS”的intent,作為參數(shù):
queryIntentActivities(new intent(“com.android.lpx.INPUMETHOD_PLUS”,flag)。
這樣每一個輸入法插件都要設(shè)置自己的intent屬性為“com.android.lpx.INPUMETHOD_PLUS”,這樣才能夠被插件管理器Switcher搜索到。
在查詢到哪一個Activity包含輸入法插件后,還要知道插件中的具體哪一個類是輸入法實現(xiàn)類;因為我們的輸入法要繼承下面要提到的AbstractInputMethod抽象類,同時java是單繼承的,所以我們還需要提供一個如代碼1所示的接口,,用來獲取插件中輸入法具體實現(xiàn)類的信息[6]。
包含com.android.lpx.INPUMETHOD_PLUS的activity要繼承這個接口并實現(xiàn)其中的方法。通過讀取這個接口,輸入法管理器,可以獲取到插件apk程序中實現(xiàn)輸入法功能的類的名字,輸入法的名字,和輸入法圖標(biāo)的資源ID號等信息。
代碼1 插件信息接口
public interface PlugInfo {
public String getName();
public String getClassName();
public Drawable getIcon();
}
4.2 輸入法插件設(shè)計
為了便于管理和加載輸入法插件,需要提供一個統(tǒng)一的輸入法接口。輸入法的基本數(shù)據(jù)流就是從屏幕/鍵盤獲取用戶原始輸入,甚至還包括用戶上一次輸入的字符(用于聯(lián)想功能);輸入數(shù)據(jù)經(jīng)過輸入法算法處理后產(chǎn)生輸入字符和候選字符以及聯(lián)想字符;將輸入字符傳送給文本輸入框,以及候選字符或者聯(lián)系字符交給輸入法管理器來顯示。代碼2中顯示了本輸入法插件設(shè)計中采用的接口[7]。
代碼2 輸入法插件接口
public interface InputMethod {
public boolean handleKey(int primaryCode, int[] keyCodes); //用戶輸入的原始按鍵值
public void handleSpecial(Object data);//用戶的書寫輸入數(shù)據(jù)甚至可以包括語音輸入數(shù)據(jù)
public void associate(String inputed);//上一次輸入的數(shù)據(jù),用于聯(lián)想
public void start(); //啟動該插件
public void close(); //關(guān)閉該插件
public void clear(); //清理變量,初始化插件狀態(tài)
public int getIconID();//獲取插件的圖標(biāo)ID
public int getId();//獲取插件的ID
public String getName();//獲取插件的名稱
public boolean special();//
public String getPackageName();//獲取插件的包名稱
public View getKeyboardView(Context context, int theme);//獲取插件的輸入視圖(可以是軟鍵盤,手寫屏等
public void setOnKeyboardActionListener(OnKeyboardActionListener listener);//當(dāng)軟鍵盤被用戶按了之后調(diào)用的回調(diào)函數(shù)
public boolean isNeedShift();//是否需要考慮shift鍵狀態(tài)
public boolean isShifted();//shift鍵狀態(tài)
public void setShifted(boolean shifted);//設(shè)置shift鍵狀態(tài)
public void updateKeyboard();//更新軟鍵盤
public View updateKeyboardView(Context context, int theme);//更新軟鍵盤樣式
public void setPreviewEnabled(boolean enable);//設(shè)置是否允許按鍵預(yù)覽
public void setPreviewCenterabled(boolean enable);
}
InputMethod提供了一個輸入法的基本輸入出,但有些操作是每個輸入法都會用到的,為此基礎(chǔ)該接口實現(xiàn)一個抽象類AbstractInputMethod。AbstractInputMethod提供了一個更詳細的輸入法插件接口,同時包含每個輸入法插件都會用到的使用函數(shù)(如isNumber()判斷用戶是否點擊了(軟)鍵盤的數(shù)字鍵),和一些函數(shù)的默認(rèn)返回值。各種輸入法插件需要實現(xiàn)以上插件。
4.3 插件式輸入法示例程序的實現(xiàn)
本插件系統(tǒng)的示例代碼是在eclipse開發(fā)工具中完成。
在eclipse中新建project,命名為Switcher,并按照Android的輸入法框架API,實現(xiàn)一個輸入法框架,主要增加一個方便用戶選擇輸入法的界面。增加類用來搜索和加載輸入法插件。具體的輸入法實現(xiàn)時則是加載用戶選擇的輸入法插件。
在eclipse中新建project,命名為QwertyPinyinInputMethod,并新建一個帶有com.android.lpx.INPUMETHOD_PLUS屬性的Activity,該Activity繼承PlugInfo 接口。并新建一個類實現(xiàn)AbstractInputMethod 接口,并實現(xiàn)輸入法中具體算法功能。
本設(shè)計中的示例輸入法插件是全鍵盤拼音輸入法(QwertyPinyinInputMethod),和全屏手寫輸入法(HandwritingInputMethod)。
編譯project,并生成apk安裝文件。
安裝輸入法管理器,和2個輸入法插件
adb installswitcher.apk
adb installpinyin.apk
adb installhandwriting.apk
在Android系統(tǒng)設(shè)置中選中我們安裝的輸入法,并在輸入框中選擇使用我們剛剛安裝輸入法。然后會彈出我們的輸入法界面,按照Switcher中設(shè)定的開關(guān),可以選擇不同的輸入法插件,來實現(xiàn)不同方式的輸入,程序執(zhí)行界面如圖3所示。
5 總結(jié)
本文介紹了Android系統(tǒng)中插件式程序的設(shè)計思路,并采用該思路設(shè)計了插件式輸入法程序。本文所論述的插件式程序設(shè)計方法還可以用于多組件式程序,如包含多種在線小游戲的游戲大廳;還可以用于應(yīng)用程序的升級更新等。
在本年底,國內(nèi)各大手機廠商和電信運營公司將推出十幾款運行Android系統(tǒng)或Android定制系統(tǒng)的手機,裝載Android系統(tǒng)的手機將會很快風(fēng)靡大陸。同時包括谷歌公司,中國移動公司等多家公司已經(jīng)推出手機應(yīng)用軟件在線商店,Android應(yīng)用軟件將會面臨很大的需求。
參考文獻:
[1] Chen J.An Introduction to Android[EB].Developer Advocate,Google I/O,2008.
[2] 陳木生.GOOGLE ANDROID手機推出市場分析[J].電子與電腦,2008(12).
[3] 王曉龍,王軒.基于Windows Mobile的智能手機漢字輸入法研究[D].哈爾濱:哈爾濱工業(yè)大學(xué),2006.
[4] 鐘茂生,王明文.軟件設(shè)計模式及其使用[J].計算機應(yīng)用,2002,22(8):32-33.
[5] google android team.Inside the Android Application Framework[EB].Google Ins,2008.
[6] Haseman C.Android Essential[M].Apress,2008:9-10.
[7] 胡明星,李雙全,張激.基于嵌入式系統(tǒng)的中文輸入法的設(shè)計與實現(xiàn)[J].計算機工程,2007(20):53-54.