android输入法02:openwnn源码解析06—候选词产生
本文将要介绍openwnn输入法,输入过程中,候选词是如何产生的。由于我们只研究前端java代码,因此我们只介绍相应的接口。实际上,输入法候选词主要是来源于后端(用c代码编写的那部分),这里涉及到一些输入法相关的模型等内容,我们在此是不做介绍的。
网上流传的openwnn源码后端都没有处理(将c转为so文件),所以都是不可直接生成可运行apk的。我编译了下C代码后的源码下载地址为:http://download.****.net/detail/xianming01/4308456。
最近看到网上有转载我的文章,但没有注明出处。由于这是系列文章单单转载一两篇读者也不一定看得懂。因此在这里做一个标记,如果看到转载的同学,可以访问我的博客http://blog.****.net/xianming01。
1、候选词来源
候选词来源分为两种,一种是需要复杂变换的,一种不需要复杂变换的。这里的定义是:
需要复杂变换:需要输入法语言模型,经过输入法后端进行变换的。
不需要复杂变换:不需要语言模型,也不需要经过输入法后端,只在前端java代码即可实现变换的。
下面我们就分别来介绍这些内容。这一部分涉及到比较多的类,列出来如下:
- 简单变换
- 复杂变换
- 辅助类
3、复杂变换
需要复杂变换的候选词来源于输入法引擎,我们来看一下文本变换的引擎接口(如何从输入获得候选词的接口)。该文件为WnnEngine:
/** * The interface of the text converter accessed from OpenWnn. * <br> * The realization class of this interface should be an singleton class. * * @author Copyright (C) 2009, OMRON SOFTWARE CO., LTD. All Rights Reserved. */ public interface WnnEngine { /* * DEFINITION OF CONSTANTS */ /** The identifier of the learning dictionary */ public static final int DICTIONARY_TYPE_LEARN = 1; /** The identifier of the user dictionary */ public static final int DICTIONARY_TYPE_USER = 2; /* * DEFINITION OF METHODS */ /** * Initialize parameters. */ public void init(); /** * Close the converter. * <br> * * OpenWnn calls this method when it is destroyed. */ public void close(); /** * Predict words/phrases. * <br> * @param text The input string * @param minLen The minimum length of a word to predict (0 : no limit) * @param maxLen The maximum length of a word to predict (-1 : no limit) * @return Plus value if there are candidates; 0 if there is no candidate; minus value if a error occurs. */ public int predict(ComposingText text, int minLen, int maxLen); /** * Convert a string. * <br> * This method is used to consecutive/single clause convert in * Japanese, Pinyin to Kanji convert in Chinese, Hangul to Hanja * convert in Korean, etc. * * The result of conversion is set into the layer 2 in the {@link ComposingText}. * To get other candidates of each clause, call {@link #makeCandidateListOf(int)}. * * @param text The input string * @return Plus value if there are candidates; 0 if there is no candidate; minus value if a error occurs. */ public int convert(ComposingText text); /** * Search words from the dictionaries. * <br> * @param key The search key (stroke) * @return Plus value if there are candidates; 0 if there is no candidate; minus value if a error occurs. */ public int searchWords(String key); /** * Search words from the dictionaries. * <br> * @param word A word to search * @return Plus value if there are candidates; 0 if there is no candidate; minus value if a error occurs. */ public int searchWords(WnnWord word); /** * Get a candidate. * <br> * After {@link #predict(ComposingText, int, int)} or {@link #makeCandidateListOf(int)} or * {@code searchWords()}, call this method to get the * results. This method will return a candidate in decreasing * frequency order for {@link #predict(ComposingText, int, int)} and * {@link #makeCandidateListOf(int)}, in increasing character code order for * {@code searchWords()}. * * @return The candidate; {@code null} if there is no more candidate. */ public WnnWord getNextCandidate(); } 以上引用的代码中,我们只是将候选词来源的接口列出来了,其他一些接口都是用来辅助的,所以未予列出。从上面我们可以看出,候选词来源包括如下途径:- 预测
- 文节变换(单文节或者多文节变换,多文节变换又称为整句变换)
- 从词典中搜索(预测实际上是以此为基础的
从词典中搜索,从字面理解就可以了。但是这里涉及到一个问题:词典格式。openwnn的词典,我估计是先用文本文件写好,然后再用某一种工具转换为现在的词典样子的。所以你去看词典,基本上看不懂。最近我们公司收购了一款基于openwnn的日文输入法,现在需要将自己的后端替换掉原来的开源后端。在研究的过程就发现,看不懂词典格式,所以很多工作就没法做了。
从词典搜索的代码没看,但是预计也就是按照词典格式去搜索,这个从实现上还是比较简单的。
我们来看一下预测的代码:
3.3 文节变换
文节变换包括两种:单文节变换和多文节变换。单文节变换是指,比如输入“かわい”,可以变换出“可愛”这个词。多文节变换是指连续输入两个单文节,实际上每个单文节都会有很多个结果,多文节变换选择其中最合适的组合作为两个单文节的组合结果。
由于这一部分跟语言关系比较大,所以没怎么看懂,就不多介绍了。
4、简单变换
这种变换直接在前端java代码中完成。主要包括两部分:1、罗马音输入;2、英数全半角片假名变换。
4.1 罗马音输入
通过这张图,大家可以想得到那几个HashMap的作用了吧。
- 虽然我们知道了这么多接口。但是输入法是如何使用这些接口并生成CandidatesView的呢?这个问题我们会在后续的文章中介绍;
- java代码是如何调用后端c代码的。这里涉及jni的内容,后续会介绍。