`
king523103
  • 浏览: 8695 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

【转】Android输入法框的梳理

阅读更多
转载地址: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和浏览器页面融为一体,效果就很好了。

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

相关推荐

    Android 输入法框架

    "Android 输入法框架" Android 输入法框架是 Android 操作系统中的一种复杂的输入机制,负责处理用户输入的文字、符号和 Emoji 等。该框架主要分布在客户端应用、输入法模块和平台部分三个位置。 客户端应用是指...

    Android输入法的打开关闭

    在Android系统中,输入法是用户与设备交互的重要部分,特别是在进行文字输入时。本文将深入探讨Android输入法的打开和关闭机制,以及如何通过编程方式实现这一功能。 首先,理解Android系统的输入法管理机制至关...

    android输入法原理分析

    【Android 输入法原理分析】 Android 输入法的实现原理主要基于Input Method Framework (IMF)框架,该框架将输入法的实现分为三个核心模块:客户端控件、输入法服务(IMMS)和输入法应用(IME)。理解这些模块及其...

    Android输入法显示与隐藏的对布局的影响

    首先,我们需要了解Android系统是如何处理输入法显示的。Android系统使用`InputMethodManager`来管理输入法的显示和隐藏。开发者可以通过调用`InputMethodManager`的相关方法来控制输入法的状态,例如`showSoftInput...

    android输入法编辑框1.6模拟应用

    可用于开发应用过程中调试各种编辑框,该应用提供了所有系统支持的编辑框

    华为Android输入法详细设计

    在Android操作系统中,输入法是用户与设备交互的重要组成部分,特别是在智能设备日益普及的今天,一个高效、便捷的输入法能极大地提升用户体验。华为作为全球知名的科技巨头,其Android输入法设计自然备受关注。这份...

    android 输入法键盘弹出与否判断和输入法键盘弹出时将界面滚动到指定位置demo

    在Android开发中,输入法键盘的管理是用户体验中不可或缺的一部分。这个"android 输入法键盘弹出与否判断和输入法键盘弹出时将界面滚动到指定位置demo"着重于解决两个关键问题:一是检测输入法键盘是否弹出,二是当...

    Android 类似搜狗输入法android源码.zip

    本压缩包"Android 类似搜狗输入法android源码.zip"包含了开发类似功能的Android输入法的一些关键源代码和相关资源,对于学习和研究Android输入法的开发具有很高的参考价值。 首先,源码中的关键组件可能包括以下几...

    Android之输入法开发简单说明.pdf

    在Android平台上开发输入法,是一个涉及到用户交互、系统服务与应用架构的复杂过程。从给定文件的【标题】和【描述】可以看出,本文档主要介绍了在Android系统中如何创建一个简单的输入法应用。通过分析【部分内容】...

    Android IMF输入法总结

    Android IMF输入法总结 Android IMF 输入法总结是 Android 1.5 新添加的一个重要功能,用来支持软键盘、各种的输入法。 IMF Input Method Framework 的主要组件包括 Input Method Manager (IMM)、Input Method (IME...

    android 输入法 可替换系统输入法

    android输入法 emoji 输入法 键盘 软键盘

    Android输入法手势程序源码.rar

    在Android平台上,输入法手势程序是一种用户交互的重要组成部分,它允许用户通过滑动手指来输入文字,提高了输入效率。这份"Android输入法手势程序源码.rar"提供的正是一个实现此类功能的应用开发源码,这对于想要...

    android输入法原理

    "Android 输入法原理详解" Android 输入法原理是 Android 操作系统中一个核心组件,负责处理用户输入的所有操作。作为一个 Service,输入法在 Android 中扮演着非常重要的角色。下面,我们将对 Android 输入法原理...

    最简单android 输入法 源代码 适合学习

    在Android平台上,开发一款输入法是一项技术挑战,它涉及到用户界面设计、事件处理、字符预测、词库管理等多个方面。本资源提供了一个简单的Android输入法源代码,非常适合初学者理解和学习。下面,我们将深入探讨这...

    android输入法

    ### Android 输入法详解 #### 一、为何关注中文输入法? 在移动设备上,中文输入法的使用极为广泛。由于中文字符数量庞大且输入方式复杂,如何通过有限的物理或虚拟按键来高效输入中文,成为了Android平台面临的一...

    android 全键盘输入法源码

    在Android系统中,全键盘输入法是用户与设备交互的重要组成部分,特别是在移动设备上,它提供了文字输入的方式。本文将深入探讨"android 全键盘输入法源码"的相关知识点,帮助开发者理解输入法的工作原理,并从中...

    基于android的应用开发源码-输入法开发.rar

    "基于Android的应用开发源码-输入法开发.rar" 是一个与Android应用开发相关的资源,特别聚焦在输入法的实现上。输入法是Android系统中一个关键组件,它允许用户在设备上输入文本,无论是通过键盘、语音还是其他交互...

    android 输入法弹出布局自动上移

    本篇文章将深入探讨如何实现"android 输入法弹出布局自动上移"这一功能,以确保在软键盘出现时,界面能够适应性地移动,类似于微信登录界面的效果。 首先,我们需要理解Android布局中的"windowSoftInputMode"属性。...

    android输入法手势程序源码

    这份"android输入法手势程序源码"是一个很好的学习资源,可以帮助开发者深入了解手势识别技术和如何将其应用于Android应用中。下面将详细探讨相关知识点。 一、Android手势输入 1. **手势识别库**:Android系统...

    android 输入法 softkeyboard

    在Android系统中,SoftKeyboard是用于开发自定义输入法的关键组件。这个官方的输入法demo为开发者提供了一个学习和理解如何构建自己的输入法应用的起点。让我们深入探讨一下这个软键盘实现背后的细节。 首先,我们...

Global site tag (gtag.js) - Google Analytics