本文转自:http://blog.csdn.net/a345017062/article/details/6121147

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

这是整个系统当中,一切与输入法有关的地方的总控制中心。它通过管理下面三个模块来实现系统的输入法框架。

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

负责显示输入法,接收用户事件。

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

输入法内部逻辑,键盘布局,选词等,最终把选出的字符通过commitText提交出来。要做一个像搜狗输入法这样的东西的话,主要就是在这里做文章。

3、InputManager

由UI控件(View,TextView,EditText等)调用,用来操作输入法。比如,打开,关闭,切换输入法等。

下面说一下InputMethodManagerService这个控制中心是怎么样与三个模块交互的。

1、与WindowManagerSerivce的交互。

首先,InputMethodManagerService在初始化时,会调用IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE)),得到IWindowManager这个代理,然后通过IWindowManager与WindowManagerService交互。比如下面这些操作:

调用mIWindowManager.addWindowToken(mCurToken, WindowManager.LayoutParams.TYPE_INPUT_METHOD),让WindowManagerService显示输入法界面。

调用mIWindowManager.removeWindowToken(mCurToken)让输入法界面关闭。

调用mIWindowManager.inputMethodClientHasFocus(client)判断输入法是否聚焦。

2、与InputMethodService的交互。

InputMethodManagerService在内部维护着一个ArrayList<InputMethodInfo> mMethodList。这个列表会在服务启动时通过PackageManager查询当前系统中的输入法程序来得到。与之对应的,每一个输入法程序的AndroidManifest.xml中都会有一个Service,而每个Service中都会有标记来告诉系统,自己是个输入法程序。下面这个是我从系统自带的例子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内部还有一个PackageReceiver,当系统中有程序的安装、删除、重启等事件发生时,会更新mMethodList。InputMethodManagerService打开,关闭,切换输入法时,其实就是在操作mMethodList中某个InputMethodInfo。把InputMethodInfo中的代表某个输入法的InputMethodService启动或者销毁,就实现了输入法的打开和关闭。

3、与InputMethodManager的交互

InputMethodManager中会包含一个IInputMethodManager,这个东西就是InputMethodManagerService的代理,打开关闭输入法这些操作就是由InputMethodManager中的某些方法调用IInputMethodManager中相应的方法来实现的。比如:

mService.getInputMethodList()获取输入法列表。

mService.updateStatusIcon(imeToken, packageName, iconId)更新输入法图标,即屏幕上方状态栏中的输入法图标。

mService.finishInput(mClient)隐藏当前输入法。这所以不说关闭输入法,是因为输入法服务启动起来以后,只有在系统关闭或者切换输入法时才会关闭。

mService.showSoftInput(mClient, flags, resultReceiver)打开当前输入法。

...

分别介绍完三大模块之后,再介绍两个东西,输入法的实现和怎么样调用输入法。

1、以系统的SoftKeyboard为例,实现一个输入法至少需要Keyboard,KeyboardView,CandidateView,SoftKeyboard这四个东西。

CandidateView负责显示软键盘上面的那个候选区域。

Keyboard负责解析并保存键盘布局,并提供选词算法,供程序运行当中使用。其中键盘布局是以XML文件存放在资源当中的。比如我们在汉字输入法下,按下b、a两个字母。Keyboard就负责把这两个字母变成爸、把、巴等显示在CandidateView上。

KeyboardView负责显示,就是我们看到的按键。

上面这两人东西合起来,组成了InputView,就是我们看到的软键盘。

SoftKeyboard继承了InputMethodService,启动一个输入法,其实就是启动一个InputMethodService,当SoftKeyboard输入法被使用时,启动就会启动SoftKeyboard这个Service。InputMethodService中管理着一个继承自Dialog的SoftInputWindow,而SoftInputWindow里面就包括了InputView和CandidateView这两个东西。

2、怎么样调用输入法呢?

说起这个东西,很自然地想起EditText来,我们团队跟踪过这个Widget,EditText本身很简单,主要的代码在TextView和View当中。这两个Widget本身又很复杂,杂在一起说不清楚。这里我就把我们团队以前做过的一个小例子拿进来做参考,说明一下如何从一个View上调用输入法和如何接收输入法传过来的字符串。

小例子的起源来自于我们要做一个浏览器,需要在SurfaceView来在Canvas上面绘制自己需要的东西,开启自己的主控制循环线程,事件处理等。比如我要在SurfaceView上绘制输入浏览器中的按钮、文本、图片、输入框等,当然这些和ImageView,TextView没有关系,都是用自己的UI引擎来做的。最后所有问题都解决了,却在输入框上卡壳了。因为要实现输入,得调用EditText,否则就必须自己去和EditText一样连接输入法。以前找过相关资料,看网上也有人碰到过这个问题,但都没有答案。最后,还是团队中一个很牛的娃给解决了。代码很简单,不出二十行,但没资料,View的源码又太庞大,费的劲却是只有我们团队的人才能体会得到的。。。这里佩服张老二同学一下,没有他的努力,就没有下面这二十多行很重要很重要的源码的诞生。

首先,定义一个继承自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) {//输入法程序就是通过调用这个方法把最终结果输出来的。

tx = text.toString();

return true;

}

}

BaseInputConnection相当于一个InputMethodService和View之间的一个通道。每当InputMethodService产生一个结果时,都会调用BaseInputConnection的commitText方法,把结果传递出来。

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);//在你想呼出输入法的时候,调用这一句。

... ...

@Override

public InputConnection onCreateInputConnection(EditorInfo outAttrs) {//这个方法继承自View。把自定义的BaseInputConnection通道传递给InputMethodService。

return new MyBaseInputConnection(this, false);

}

}

低级界面上面,自己调用输入法并接收输入法的输出结果,就是这样的。

下面我想提一下和这个话题相关的另外一件事,就是前面解决过的一个Bug:

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

通过这个问题,可以看出WebView上面的输入法是如何实现的。简单来说,WebView就是一个ViewGroup,它里面有两层,上层是一个EditText,下层是浏览器页面。当浏览器的输入框被用户点中,需要显示输入法时,就把上层EditText的位置移到浏览器的输入框的位置,高速好EditText的大小和样式后,让EditText和浏览器页面融为一体,效果就很好了。

通常来说,这个方式应该比自己调用输入法要好些。可以少做很多事。不过,如果产品经理是个很有想像力的人的话,你就不能满足他设计出来的有可能极端变态却非常炫的输入效果了。

转载于:https://www.cnblogs.com/freeliver54/archive/2011/09/08/2171339.html

[转]Android输入法框的梳理相关推荐

  1. android弹出输入框不影响布局,android 输入法弹出后,不影响activity原有布局

    android输入法弹出框有时会遮挡原有的布局,使得输入法弹出框弹出时,原布局消失,现介绍android:windowSoftInputMode的一些属性: 在AndroidManifest.xml文 ...

  2. 实现一个Android输入法

    原文来自 Android Developer Guide,本文为原文翻译,如有错误,欢迎指出. 输入法(IME:Input method editor)是一个能够让用户输入文本的工具.Android提 ...

  3. 浅谈Android输入法(IME)架构

    简介: 输入法 (IME) 是一种可让用户输入文本的用户控件.Android 提供了一种可扩展的输入法框架.借助该框架,应用可以为用户提供备选输入法,例如屏幕键盘,甚至语音输入.安装所需的 IME 后 ...

  4. Android模拟器检测体系梳理

    转自:https://www.wireghost.cn/2018/05/10/Android模拟器检测体系梳理/ 模拟器作为一种虚拟机,配合改机工具,能够以较低成本实现设备多开,因此而备受黑灰产的青睐 ...

  5. Android输入法架构学习总结

    此文为本人学习输入法之后所做的一个总结报告.与大家分享. 安卓输入法框架(Input Method Framework)IMF 一.输入法框架简介 自Android平台1.5版本以后,Google开放 ...

  6. Android 输入法挤压屏幕解决方案

    问题发生 Android 输入法问题真是太蛋疼了, 我有这样一个需求, 要在图片上加字, 上图看效果: 然后我要双击编辑的时候需要一个编辑框, 但是界面之前是没有任何编辑框的, 我的想法是在底部生成一 ...

  7. android输入法开发软件,开发安卓系统Android和码输入法软件的全过程(二)

    2012年01月20日星期五 Android IMF给输入软件的编写给出的规范,也提供了很多的方便.这里从例子程序SoftKeyboard来认识. 1.软键盘界面的设计,可以用XML文件来做,这真是很 ...

  8. Android 输入法 微信公众号搜索定制版

    1. 一个简单的Android 输入法 (1) 使用Android Studio建立一个没有Activity的项目,对于一个简单的输入法而言,MainActivity并不是必要的,只需要一个输入法服务 ...

  9. android输入法机制的学习总结

    android输入法机制包含三部分: 输入法服务(InputMethodService),简称IMS: 输入法系统服务(InputMethodManagerService),简称IMMS: 客户端ap ...

最新文章

  1. idea git 使用
  2. mysql主从 1050错误
  3. GDCM:gdcm::Global的测试程序
  4. POJ3009-Curling 2.0
  5. mysql使用小技巧_MySQL使用小技巧
  6. python 百度云文字识别 proxy_python使用百度文字识别功能方法详解
  7. numcpp速度对比_PHP和C++性能对比.pdf
  8. mysql 查看锁_别吵吵,分布式锁也是锁
  9. textbox内容转为字符串_【公告】整改文章内容
  10. 如何用vs2013开发人员命令提示工具执行一个方法(一个简单的demo)
  11. 如何在Win10中运行Win7小游戏 扫雷,蜘蛛纸牌,红心大战,纸牌,空当接龙?
  12. cdr三角形转化为圆角_cdr怎么把直角变成圆角
  13. select into from 与 insert into select用法详解
  14. java 第三方微信平台_微信公众账号第三方平台全网发布源码(java-jeewx)
  15. 总结VS下opencv无法正常显示图片的几种问题及其解决方案
  16. SonarQube 初探
  17. 计算机专业笔记本低压,笔记本win7系统下CPU低压u和标压m的区别对比
  18. 马克下, 初识 runtime (一)
  19. 【科研技巧】Mac下使用SciDavis绘制科研论文图教程(安装及使用)
  20. 学术英语社科Unit8原文翻译

热门文章

  1. Altium Designer -- PCB 叠层设计
  2. pat天梯赛L1-053. 电子汪
  3. 复习1 - String,StringBuilder,StringBuffer的执行效率区别
  4. 用区块链改变人工智能:去中心化带来数据新范式
  5. 资源隔离之 Linux namespace
  6. IPFS + 区块链 系列】 入门篇 - IPFS + Ethereum (上篇)-js-ipfs-api
  7. 梳理各算法基础应用及场景
  8. JZOJ 5263. 【NOIP2017模拟8.12A组】分手是祝愿
  9. cascade在java_【Java基础】集合
  10. 全国计算机二级qq闪退,电脑上QQ闪退怎么回事?各个系统版本电脑QQ闪退现象的解决方法介绍...