Google原生输入法LatinIME引擎初始化流程分析(二)
引擎初始化首先是在Java层调用native的初始化方法,Java层调用如下:
private void initPinyinEngine() {byte usr_dict[];usr_dict = new byte[MAX_PATH_FILE_LENGTH];// Here is how we open a built-in dictionary for access through// a file descriptor...AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.dict_pinyin);if (Environment.getInstance().needDebug()) {Log.i("foo", "Dict: start=" + afd.getStartOffset()+ ", length=" + afd.getLength() + ", fd="+ afd.getParcelFileDescriptor());}if (getUsrDictFileName(usr_dict)) {inited = nativeImOpenDecoderFd(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(), usr_dict);}try {afd.close();} catch (IOException e) {}}
根据构建后的二进制文件获取 一个文件描述符,将该文件描述符传入native进行初始化,其实就是load之前build中产生的一些数组、树结构以及一些值,native经过一些列调用,最终是调用用了matrixsearch类的init方法:
bool MatrixSearch::init_fd(int sys_fd, long start_offset, long length,const char *fn_usr_dict) {if (NULL == fn_usr_dict)return false;if (!alloc_resource())return false;LOGD("init_fd sys_fd == %d , start_offset == %l, and length == %l", sys_fd, start_offset, length);if (!dict_trie_->load_dict_fd(sys_fd, start_offset, length, 1, kSysDictIdEnd))return false;LOGD("fn_usr_dict == %c", *fn_usr_dict);if (!user_dict_->load_dict(fn_usr_dict, kUserDictIdStart, kUserDictIdEnd)) {delete user_dict_;user_dict_ = NULL;} else {user_dict_->set_total_lemma_count_of_others(NGram::kSysDictTotalFreq);}LOGD("size of dict_trie == %d", sizeof(dict_trie_));reset_search0();inited_ = true;return true;
}
调用了两个load_dict,一个是dict_trie的,用来加载sys_fd,这个sys_fd就是build后生成的二进制文件dict_pinyin.dat文件,这里使用其文件描述符来进行加载操作,另一个是调用user_dict的load_dict方法,此方法用来加载用户词典,fn_usr_dict变量为:/data/user/0/com.android.inputmethod.latin/files/user_dict.dat文件,这个dat文件是用户在使用输入法过程中产生的用户字典,初次安装应用的话用户字典初始状态为空,因此初始化的过程主要逻辑在加载系统词典:
bool DictTrie::load_dict_fd(int sys_fd, long start_offset,long length, LemmaIdType start_id,LemmaIdType end_id) {if (start_offset < 0 || length <= 0 || end_id <= start_id)return false;FILE *fp = fdopen(sys_fd, "rb");if (NULL == fp)return false;if (-1 == fseek(fp, start_offset, SEEK_SET)) {fclose(fp);return false;}free_resource(true);dict_list_ = new DictList();if (NULL == dict_list_) {fclose(fp);return false;}SpellingTrie &spl_trie = SpellingTrie::get_instance();NGram &ngram = NGram::get_instance();if (!spl_trie.load_spl_trie(fp) || !dict_list_->load_list(fp) ||!load_dict(fp) || !ngram.load_ngram(fp) ||ftell(fp) < start_offset + length ||total_lma_num_ > end_id - start_id + 1) {free_resource(true);fclose(fp);return false;}fclose(fp);return true;
}
主要加载逻辑都在第四个if语句中:
1、spl_trie.load_spl_trie()从stream中读取相关数据结构并组织拼音树结构。
2、dict_list_->load_list(fp)从fp中读取单汉字列表scis以及buf_413个合法音节数组等,load_list的过程和save_list的流程相同,按照save的顺序去读取对应的数组:scis_num_、start_pos_、start_id_、scis_hz_、scis_splid_和buf_。
3、load_dict(fp)从fp中恢复lma_node_num_le0_、lma_node_num_ge1_、lma_idx_buf_len_、top_lmas_num_、lma_idx_buf_、nodes_ge1_和root_。
4、ngram.load_ngram(fp)从fp中加载build的时候save的数组和数值:idx_num_、freq_codes_、lma_freq_idx_,关于ngram信息构建流程可以参考前面的Google原生输入法LatinIME词库构建流程分析(三)--N-gram信息构建
综上,load_dict的流程其实就是把build过程中的一些数组和数值从二进制文件流中按照保存次序一次读取出来,在search或者predict的过程中,综合这些数据结构实现输入文字的查找、预测过程。
Google原生输入法LatinIME引擎初始化流程分析(二)相关推荐
- Google原生输入法LatinIME词库构建流程分析(二)
在Google原生输入法LatinIME词库构建流程分析(一) 中分析LatinIME构建流程进行到了dict_trie->dict_list_->init_list这一步,然后就是构建N ...
- Google原生输入法LatinIME词库构建流程分析(三)--N-gram信息构建
N-gram信息的构建在ngram.cpp中进行构建: bool NGram::build_unigram(LemmaEntry *lemma_arr, size_t lemma_num,LemmaI ...
- Google原生输入法LatinIME词库构建流程分析--相关数据结构分析
其实输入法词库相关数据结构的定义基本上都在头文件dictdef.h文件中,进入到代码目录cpp下. 初始化字库,首先读取txt文件内容到数据结构lemma_arr和valid_hzs中,lemma_a ...
- Google原生输入法LatinIME词库扩容(Windows10环境)
去年在Linux(ubuntu)环境下针对LatinIME进行词库扩容处理,针对LatinIME的词库构建进行了一些列分析,大家可以查阅历史文章.词库扩容最近试了一下是可以的,具体流程大致如下(win ...
- 【Android Camera1】Camera1初始化销毁流程(一) —— 官方Demo初始化流程分析
Camera1初始化流程 一.摘要 二.Camera1 Demo分析 2.1 变量解析 2.2 构造函数 setUpPreview() adjustCameraParameters() 2.3 Sta ...
- 第七章 frr sysrepo纳管初始化流程分析
本章节主要是通过分析frr sysrepo纳管实现来讲讲frr-7.5是如何实现对sysrepo的支持.以isis协议纳管实现为例.了解本章节的内容需要先了解前面章节的内容.本章节的内容不会过多重复前 ...
- android6.0源码分析之Camera API2.0下的初始化流程分析
1.Camera2初始化的应用层流程分析 Camera2的初始化流程与Camera1.0有所区别,本文将就Camera2的内置应用来分析Camera2.0的初始化过程.Camera2.0首先启动的是C ...
- OSAL初始化流程分析
我使用的协议栈版本及例子信息: ZigBee2006\Texas Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Samples\SampleApp ...
- Linphone_android jni下音视频流、初始化流程分析
本来流程顺序上面做了排版(函数内部的流程,加了tab缩进的)方便理解, 但是发表之后,还是乱了. 流程顺序基本理清了,可以复制到notepad++,手动加下缩进吧. 主流程是序号 1.2.... 函数 ...
最新文章
- 1080 线段树练习
- 简单的3个SQL视图搞定所有SqlServer数据库字典
- java包含点_Java的21个核心技术点,你知道吗
- success for advertisement
- 如何安装MiniGUI 3.0在Linux PC
- 优秀小程序demo 源码
- linux中设备配额 磁盘加密
- vs配置opencv
- WebSphere 安装和配置过程
- gbase数据库锁表解决办法
- jdk1.8的新特性之--Rhion变为Nashorn
- jdk和cglib动态代理
- Thinkphp响应式第三四方聚合支付平台源码
- ssrf dict MySQL_SSRF之利用dict和gopher吊打Redis
- 2018 东北四省赛
- 手把手带你爬天猫,获取杜蕾斯评论数据
- 【Python】检测下载不完整、半截灰色的JPG、JPEG、PNG图片脚本
- mysql候选关键字_MySQL(三)之SQL语句分类、基本操作、三大范式
- [软件安装] Apache Httpd 安装教程
- 多线程之 ForkJoinool线程池(二十四)