【Android源码 栏目提醒】:网学会员鉴于大家对Android源码 十分关注,论文会员在此为大家搜集整理了“android输入法02:openwnn源码解析06—候选词产生 - 网络与通信”一文,供大家参考学习
android 输入法 02:openwnn
源码解析 06—候选词产生 本文将要介绍 openwnn 输入法,输入过程中,候选词是如何产生的。
由于我们只研究前端java 代码,因此我们只介绍相应的接口。
实际上,输入法候选词主要是来源于后端(用 c 代码编写的那部分),这里涉及到一些输入法相关的模型等内容,我们在此是不做介绍的。
网上流传的 openwnn
源码后端都没有处理(将 c 转为 so 文件),所以都是不可直接生成可运行 apk 的。
我编译了下 C 代码后的
源码下载地址为:http://download.csdn.net/detail/xianming01/4308456。
最近看到网上有转载我的文章,但没有注明出处。
由于这是系列文章单单转载一两篇读者也不一定看得懂。
因此在这里做一个标记,如果看到转载的同学,可以访问我的博客http://blog.csdn.net/xianming01。
1、候选词来源 候选词来源分为两种,一种是需要复杂变换的,一种不需要复杂变换的。
这里的定义是:需要复杂变换:需要输入法语言模型,经过输入法后端进行变换的。
不需要复杂变换:不需要语言模型,也不需要经过输入法后端,只在前端 java 代码即可实现变换的。
下面我们就分别来介绍这些内容。
这一部分涉及到比较多的类,列出来如下: 简单变换LetterConverter.javaRomkan.javaRomkanFullKatakana.javaRomkanHalfKatakana.javaKanaConverter.java 复杂变换WnnEngine.javaOpenWnnEngineJAJP.javaOpenWnnClauseConverterJAJP.javaOpenWnnDictionaryImpl.javaOpenWnnDictionaryImplJni.java 辅助类ComposingText.java2、 ComposingText 这是一个比较关键的类,在很多代码中都有涉及到。
所以我们拿出来介绍一下。
该类实际上是表示的是当前正在编辑的串,也就是在输入框有个下划线的那一部分。
其类中的变量定义如下:javaviewplaincopyprint 1. / 2. Thecontainerclassofcomposingstring. 3. 4. Thisinterfaceisfortheclassincludesinformationaboutthe 5. inputstringtheconvertedstringanditsdecoration. 6. linkLetterConverterandlinkWnnEnginegettheinputstringfromitand 7. storetheconvertedstringintoit. 8. 9. authorCopyrightC2009OMRONSOFTWARECO.LTD.AllRightsReserved. 10. / 11. publicclassComposingText 12. / 13. Textlayer0. 14. 15. Thistextlayerholdskeystrokes. 16. exRomajiinJapanese.PartsofHangulinKorean. 17. / 18. publicstaticfinalintLAYER00 19. / 20. Textlayer1. 21. 22. Thistextlayerholdstheresultoftheletterconverter. 23. exHiraganainJapanese.PinyininChinese.HangulinKorean. 24. / 25. publicstaticfinalintLAYER11 26. / 27. Textlayer2. 28. 29. Thistextlayerholdstheresultoftheconsecutiveclauseconverter. 30. extheresultofKana‐to‐KanjiconversioninJapanese 31. Pinyin‐to‐KanjiconversioninChineseHangul‐to‐ HanjaconversioninKoreanlanguage. 32. / 33. publicstaticfinalintLAYER22 34. /Maximumnumberoflayers/ 35. publicstaticfinalintMAX_LAYER3 36. 37. /Composingtextslayerdata/ 38. protectedArrayListmStringLayer 39. /Cursorposition/ 40. protectedintmCursor 这里将词分为三层,以日文为例:第一层是你输入的按键信息;第二层是假名;第三层是汉字信息。
第三层由第二层得到,第二层由第一层得到。
比如,上面的两个图,第一个图显示的是第二层的信息,第二层显示的是第三层的信息(按一下“变换”键)。
另外,这一个类,还用于编辑文节。
因为你按下左箭头或者右箭头,可以选择整个串的不同部分。
这一部分的具体代码我也没怎么看懂?3、复杂变换 需要复杂变换的候选词来源于输入法引擎,我们来看一下文本变换的引擎接口(如何从输入获得候选词的接口)。
该文件为 WnnEngine:javaviewplaincopyprint 1. / 2. TheinterfaceofthetextconverteraccessedfromOpenWnn. 3. 4. Therealizationclassofthisinterfaceshouldbeansingletonclass. 5. 6. authorCopyrightC2009OMRONSOFTWARECO.LTD.AllRightsReserved. 7. / 8. publicinterfaceWnnEngine 9. / 10. DEFINITIONOFCONSTANTS 11. / 12. /Theidentifierofthelearningdictionary/ 13. publicstaticfinalintDICTIONARY_TYPE_LEARN1 14. /Theidentifieroftheuserdictionary/ 15. publicstaticfinalintDICTIONARY_TYPE_USER2 16. 17. / 18. DEFINITIONOFMETHODS 19. / 20. / 21. Initializeparameters. 22. / 23. publicvoidinit 24. 25. / 26. Closetheconverter. 27. 28. 29. OpenWnncallsthismethodwhenitisdestroyed. 30. / 31. publicvoidclose 32. 33. / 34. Predictwords/phrases. 35. 36. paramtextTheinputstring37. paramminLenTheminimumlengthofawordtopredict0:nolimit38. parammaxLenThemaximumlengthofawordtopredict‐1:nolimit39. returnPlusvalueiftherearecandidates0ifthereisnocandida teminusvalueifaerroroccurs.40. /41. publicintpredictComposingTexttextintminLenintmaxLen42.43. /44. Convertastring.45. 46. Thismethodisusedtoconsecutive/singleclauseconvertin47. JapanesePinyintoKanjiconvertinChineseHangultoHanja48. convertinKoreanetc.49. 50. Theresultofconversionissetintothelayer2inthelinkComposingText .51. TogetothercandidatesofeachclausecalllinkmakeCandidateListOfint .52. 53. paramtextTheinputstring54. returnPlusvalueiftherearecandidates0ifthereisnocandidate minusvalueifaerroroccurs.55. /56. publicintconvertComposingTexttext57.58. /59. Searchwordsfromthedictionaries.60. 61. paramkeyThesearchkeystroke62. returnPlusvalueiftherearecandidates0ifthereisnocandidate minusvalueifaerroroccurs.63. /64. publicintsearchWordsStringkey65.66. /67. Searchwordsfromthedictionaries.68. 69. paramwordAwordtosearch70. returnPlusvalueiftherearecandidates0ifthereisnocandida teminusvalueifaerroroccurs.71. / 72. publicintsearchWordsWnnWordword 73. 74. / 75. Getacandidate. 76. 77. AfterlinkpredictComposingTextintintorlinkmakeCandidateListO fintor 78. codesearchWordscallthismethodtogetthe 79. results.Thismethodwillreturnacandidateindecreasing 80. frequencyorderforlinkpredictComposingTextintintand 81. linkmakeCandidateListOfintinincreasingcharactercodeorderfor 82. codesearchWords. 83. 84. returnThecandidatecodenullifthereisnomorecandidate. 85. / 86. publicWnnWordgetNextCandidate 87. 以上引用的代码中,我们只是将候选词来源的接口列出来了,其他一些接口都是用来辅助的,所以未予列出。
从上面我们可以看出,候选词来源包括如下途径: 预测 文节变换(单文节或者多文节变换,多文节变换又称为整句变换) 从词典中搜索(预测实际上是以此为基础的3.2 预测(词典搜索) 从词典中搜索,从字面理解就可以了。
但是这里涉及到一个问题:词典格式。
openwnn 的词典,我估计是先用文本文件写好,然后再用某一种工具转换为现在的词典样子的。
所以你去看词典,基本上看不懂。
最近我们公司收购了一款基于 openwnn 的日文输入法,现在需要将自己的后端替换掉原来的开源后端。
在研究的过程就发现,看不懂词典格式,所以很多工作就没法做了。
从词典搜索的代码没看,但是预计也就是按照词典格式去搜索,这个从实现上还是比较简单的。
我们来看一下预测的代码:javaviewplaincopyprint 1. publicintpredictComposingTexttextintminLenintmaxLen 2. clearCandidates 3. iftextnullreturn0 4. 5. /setmInputHiraganaandmInputRomaji/ 6. intlensetSearchKeytextmaxLen 7. 8. /setdictionariesbythelengthofinput/ 9. setDictionaryForPredictionlen 10. 11. /searchdictionaries/ 12. mDictionaryJP.setInUseStatetrue 13. 14. iflen0 15. /searchbypreviouslyselectedword/ 16. returnmDictionaryJP.searchWordWnnDictionary.SEARCH_LINKWnnDictionary .ORDER_BY_FREQUENCY 17. mInputHiraganamPreviousWord 18. else 19. ifmExactMatchMode 20. /exactmatching/ 21. mDictionaryJP.searchWordWnnDictionary.SEARCH_EXACTWnnDictionary.O RDER_BY_FREQUENCY 22. mInputHiragana 23. else 24. /prefixmatching/ 25. mDictionaryJP.searchWordWnnDictionary.SEARCH_PREFIXWnnDictionary. ORDER_BY_FREQUENCY 26. mInputHiragana 27. 28. return1 29. 30. 预测,实际上就是去词典搜索结果。
这里有两种模式,一种是完全匹配,一种是前缀匹配。
前者,比如你输入“zhongguo”,则可以得到词典中,读音为“zhongguo”的结果,比如“中国”、“种过”等;后者,比如你输入“zhongguo”,在词典中搜索到“中国人民”,“中国人民共和国”等结果。
3.3 文节变换 文节变换包括两种:单文节变换和多文节变换。
单文节变换是指,比如输入“かわい”,可以变换出“可爱”这个词。
多文节变换是指连续输入两个单文节,实际上每个单文节都会有很多个结果,多文节变换选择其中最合适的组合作为两个单文节的组合结果。
由于这一部分跟语言关系比较大,所以没怎么看懂,就不多介绍了。
4、简单变换 这种变换直接在前端 java 代码中完成。
主要包括两部分:1、罗马音输入;2、英数全半角片假名变换。
4.1 罗马音输入 罗马音输入,是指,你输入拼音,输入法根据拼音生成相应的假名(类似于拼音输入)。
比如你输入kawai,则显示的结果为かわい,这其中就涉及到将 ka 变换为か的操作。
这种输入方式,通常存在于全键盘的情况下。
但是我发现,我编译的 openwnn
源码是没有全键盘的,所以无法使用这个功能的。
我下载了一个 simeji 日文输入法(基于 openwnn 开发的),其全键盘形式如下: 这一部分是在这四个类中完成的:LetterConverter.javaRomkan.javaRomkanFullKatakana.javaRomkanHalfKatakana.java 实际上大家看
源码,就是根据 HashMap 中国查找得出结果的。
比如 Romkan.java 中romkanTable 类的内容为:javaviewplaincopyprint 1. putlaぁputxaぁputaあ 2. putliぃputlyiぃputxiぃ 3. putxyiぃputiいputyiい 这就是为什么,你输入 li,会得到ぃ的原因。
4.2 英数全半角片假名变换这些东西在类 KanaConverter.java 中完成。
这个类的具体变换过程我就不介绍了。
我介绍一下其中的几个 HashMap,看完这个大家估计就懂了。
mHanSuujiMap 的内容类似:javaviewplaincopyprint 1. putあ1 2. putい11 3. putう111 4. putえ1111 5. putお11111 6. putか2 7. putき22 8. putく222 9. putけ2222 10. putこ22222mZenSuujiMap:javaviewplaincopyprint 1. putあ1 2. putい11 3. putう111mHanKataMap:javaviewplaincopyprint 1. putあ 2. putい 3. putう 然后大家在使用时,比如输入“あ”,按“英数”键,可以得到如下结果: 通过这张图,大家可以想得到那几个 HashMap 的作用了吧。
5、结语 通过以上的介绍,大家应该对 openwnn 日文输入法候选词的产生有了一定的了解了。
这里还涉及到两个问题: 虽然我们知道了这么多接口。
但是输入法是如何使用这些接口并生成 CandidatesView 的 呢?这个问题我们会在后续的文章中介绍; java 代码是如何调用后端 c 代码的。
这里涉及 jni 的内容,后续会介绍。