`
waterlife
  • 浏览: 67852 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Android Framework系列之IMF(三)

阅读更多

原创文章,转载请标注出处----

 

我们知道当一个编辑框获得焦点的时候,将会create一个新的IME客户端,那么IMF框架是怎样处理这个事件的呢?

 

首先调用EditText的构造函数EditTex->TextView->setText()           

 InputMethodManager imm = InputMethodManager.peekInstance();
 if (imm != null) imm.restartInput(this);

 

->startInputInner

 

    void startInputInner() {
        final View view;
        synchronized (mH) {
            view = mServedView;
            
            // Make sure we have a window token for the served view.
            if (DEBUG) Log.v(TAG, "Starting input: view=" + view);
            if (view == null) {
                if (DEBUG) Log.v(TAG, "ABORT input: no served view!");
                return;
            }
        }
        
        // Now we need to get an input connection from the served view.
        // This is complicated in a couple ways: we can't be holding our lock
        // when calling out to the view, and we need to make sure we call into
        // the view on the same thread that is driving its view hierarchy.
        Handler vh = view.getHandler();
        if (vh == null) {
            // If the view doesn't have a handler, something has changed out
            // from under us, so just bail.
            if (DEBUG) Log.v(TAG, "ABORT input: no handler for view!");
            return;
        }
        if (vh.getLooper() != Looper.myLooper()) {
            // The view is running on a different thread than our own, so
            // we need to reschedule our work for over there.
            if (DEBUG) Log.v(TAG, "Starting input: reschedule to view thread");
            vh.post(new Runnable() {
                public void run() {
                    startInputInner();
                }
            });
            return;
        }
        
        // Okay we are now ready to call into the served view and have it
        // do its stuff.
        // Life is good: let's hook everything up!
        EditorInfo tba = new EditorInfo();
        tba.packageName = view.getContext().getPackageName();
        tba.fieldId = view.getId();
        InputConnection ic = view.onCreateInputConnection(tba); //create 新的InputConnection 
        if (DEBUG) Log.v(TAG, "Starting input: tba=" + tba + " ic=" + ic);
        
        synchronized (mH) {
            // Now that we are locked again, validate that our state hasn't
            // changed.
            if (mServedView != view || !mServedConnecting) {
                // Something else happened, so abort.
                if (DEBUG) Log.v(TAG, 
                        "Starting input: finished by someone else (view="
                        + mServedView + " conn=" + mServedConnecting + ")");
                return;
            }
            
            // If we already have a text box, then this view is already
            // connected so we want to restart it.
            final boolean initial = mCurrentTextBoxAttribute == null;
            
            // Hook 'em up and let 'er rip.
            mCurrentTextBoxAttribute = tba;
            mServedConnecting = false;
            mServedInputConnection = ic;
            IInputContext servedContext;
            if (ic != null) {
                mCursorSelStart = tba.initialSelStart;
                mCursorSelEnd = tba.initialSelEnd;
                mCursorCandStart = -1;
                mCursorCandEnd = -1;
                mCursorRect.setEmpty();
                servedContext = new ControlledInputConnectionWrapper(vh.getLooper(), ic);
            } else {
                servedContext = null;
            }
            
            try {
                if (DEBUG) Log.v(TAG, "START INPUT: " + view + " ic="
                        + ic + " tba=" + tba + " initial=" + initial);
                InputBindResult res = mService.startInput(mClient,
                        servedContext, tba, initial, mCurMethod == null); //启动IMEservice
                if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res);
                if (res != null) {
                    if (res.id != null) {
                        mBindSequence = res.sequence;
                        mCurMethod = res.method;
                    } else {
                        // This means there is no input method available.
                        if (DEBUG) Log.v(TAG, "ABORT input: no input method!");
                        return;
                    }
                }
                if (mCurMethod != null && mCompletions != null) {
                    try {
                        mCurMethod.displayCompletions(mCompletions);
                    } catch (RemoteException e) {
                    }
                }
            } catch (RemoteException e) {
                Log.w(TAG, "IME died: " + mCurId, e);
            }
        }
    

 那么到了IME部分的流程又是如何的呢?

首先收到configure change的event调用onConfigurationChanged->inputmethodservice.onConfigurationChanged(conf)

 @Override public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        
        boolean visible = mWindowVisible;
        int showFlags = mShowInputFlags;
        boolean showingInput = mShowInputRequested;
        CompletionInfo[] completions = mCurCompletions;
        initViews();
        mInputViewStarted = false;
        mCandidatesViewStarted = false;
        if (mInputStarted) {
            doStartInput(getCurrentInputConnection(),
                    getCurrentInputEditorInfo(), true);  //调用startinput,创建IME的input
        }
        if (visible) {
            if (showingInput) {
                // If we were last showing the soft keyboard, try to do so again.
                if (onShowInputRequested(showFlags, true)) {
                    showWindow(true);
                    if (completions != null) {
                        mCurCompletions = completions;
                        onDisplayCompletions(completions);
                    }
                } else {
                    hideWindow();
                }
            } else if (mCandidatesVisibility == View.VISIBLE) {
                // If the candidates are currently visible, make sure the
                // window is shown for them.
                showWindow(false);
            } else {
                // Otherwise hide the window.
                hideWindow();
            }
        }
    }

 doStartInput->initialize->onInitializeInterface->onStartInput->onStartInputView.

onStartInputView中会handle各种IME的event并进一步调用IME自身的onCreate函数,做进一步的初始化以及receiver的rigister。

 

分享到:
评论

相关推荐

    Android IMF输入法总结

    IMF Input Method Framework 的主要组件包括 Input Method Manager (IMM)、Input Method (IME) 和 Client Applications。 1. Input Method Manager (IMM):相当于客户端的 API,协调其它部分的互动,负责跟系统...

    Android开发实例详解之IMF(Android_SDK_Sample—SoftKeyboard).pdf

    ### Android开发实例详解之IMF (Android_SDK_Sample—SoftKeyboard) #### 一、IMF简介 在深入了解SoftKeyboard项目之前,我们先简要介绍一下IMF(Input Method Framework)。随着Android SDK 1.5版本的发布,...

    Android-development-sample---IMF.rar_Android softKeyboard_androi

    【标题】"Android-development-sample---IMF.rar"与"Android softKeyboard_androi"结合,意味着这是一个关于Android开发的示例项目,特别关注于实现输入法框架(Input Method Framework,简称IMF),并且涉及到软...

    谷歌输入法框架 IMF

    输入法框架(Input Method Framework,IMF)是Android系统中用于管理用户输入方式的核心组件,主要涉及输入法管理器、输入法(IME)以及客户端应用。这个框架允许开发者创建自定义的输入法,并与系统中的各种应用...

    Android平台输入法开发解析

    Android 平台输入法开发解析是 Android 平台的一个重要组件,自 Android 1.5 版本以来,Android 平台开放了输入法框架(Input Method Framework,IMF),使得 Android 平台的输入法开发变得更加灵活和可扩展。...

    OpenWnn Android输入法源代码JAVA

    日文,中文,英文。 OpenWnn for Android is a IME(Input Method Editor) package which works on Android's IMF(Input Method Framework). This version contains Japanese, Chinese and English IME.

    android输入法原理分析

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

    android输入法

    - **Android JNI特殊之处**:Android的JNI环境有一些特定的要求,比如需要遵守特定的目录结构。 - **打包安装**:完成开发后,需要将生成的`.so`文件放入`libs/armeabi`目录,并通过`System.load("xxx")`加载。 ###...

    OpenWnnAndroid输入法源代码Android开发网

    可能对研究输入法的朋友有些帮助: OpenWnn for Android is a IME(Input Method Editor) package ... works on Android's IMF(Input Method Framework). This version contains Japanese, Chinese and English IME.

    Android-Hard-Soft-Key文档

    自Android 1.5版本起,引入了输入方法框架(Input Method Framework,简称IMF),旨在规范应用程序与用户选择的当前输入方法之间的交互。这一框架的出现,源于随着Android系统的发展,更多的硬件、软件设备以及输入...

    eclipse android4.4.2源码

    6. **Input Method Framework (IMF)**:改进了输入法框架,支持更丰富的键盘布局和交互方式,为第三方输入法提供了更好的平台。 7. **多用户支持**:API Level 19首次引入了多用户支持,允许多个用户在同一设备上...

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

    Android系统提供了一个输入法框架(Input Method Framework,IMF),允许开发者创建自定义的输入法。这个框架包括输入法服务(InputMethodService)和输入法编辑器(InputMethodEditor)两部分,用于处理用户输入...

    android_8 ppt (吉林大学android课程英文讲义)

    在Android开发中,输入法框架(Input Method Framework,IMF)是极其重要的一部分,特别是随着Android的成熟和发展,越来越多的硬件/软件设备和输入技术的出现,如实体键盘、虚拟键盘、语音识别、手写输入等。...

    Android开发实例详解之IMFAndroidSDKSampleSoftKeyboard.pdf

    在Android开发中,输入法(Input Method Framework, IMF)是一个重要的组成部分,特别是在涉及到用户与设备交互,特别是文本输入时。本文将深入讲解Android开发实例,具体聚焦于IMFAndroidSDKSampleSoftKeyboard项目...

    Android中文输入法实现-杨武

    IMF即输入方法框架(Input Method Framework),它是Android系统中用于管理输入法的核心组件。了解其结构对于开发自定义输入法至关重要。IMF的架构涉及多个层次,包括但不限于`android.view.ViewRoot`和`...

    基于Android平台的“字元码”输入法研究与实现.pdf

    Android是一种基于Linux的开源操作系统,其输入方法框架(Android Input Method Framework,IMF)由输入法管理器、输入法(IME)和客户端应用三部分构成,用于管理交互和文本生成。Android SDK是Android平台的软件...

    安卓平台输入法开发解析

    自Android 1.5版本以来,谷歌引入了输入法框架(Input Method Framework,简称IMF),这是Android平台的一项特色设计,旨在支持没有物理键盘的设备进行文字输入。IMF的开放不仅推动了触屏设备的普及,还提供了高度的...

    安卓Andriod源码——注释过的谷歌输入法PinyinIME源码.zip

    4. **输入法框架(Input Method Framework, IMF)**: Android的输入法框架负责管理所有输入法服务。PinyinIME源码会展示如何与IMF通信,例如如何响应系统的输入请求,以及如何通过InputConnection接口发送用户输入...

    马托斯的教程总结

    至于Input Method Framework (IMF),它处理软硬件键盘的交互,确保输入法的正确工作。 这些知识点构成了Android应用开发的基础,对理解和实践Android编程至关重要。通过深入学习和实践,开发者能够构建功能丰富的、...

    输入法介绍

    自从Android平台1.5版本之后,谷歌推出了Android平台的输入法框架(Input Method Framework, IMF),这是一项重要的技术革新,极大地推动了无物理键盘设备的发展,并且增强了软件的灵活性和可扩展性。 ##### 输入法...

Global site tag (gtag.js) - Google Analytics