手机上的英文win10输入法默认英文设计架构是什么样的

您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
android平台中文输入法设计和实现学士学位论文.doc66页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
文档加载中...广告还剩秒
需要金币:250 &&
你可能关注的文档:
··········
··········
硕 士 学 位 论 文
Android平台中文输入法的设计和实现
The Design and Implementation of Chinese Input Method
on Android
研究生姓名 指导教师姓名 专业名称
计算机技术 研究方向 中文信息处理 论文提交日期 苏州大学学位论文独创性声明及使用授权声明
学位论文独创性声明
研究生签名: 日
期: 学位论文使用授权声明
研究生签名:
期: 导师签名: 日
期: 学位论文原创性声明
本人郑重声明:所呈交的论文是本人在导师的指导下独立进行研究所取得的研究成果。除了文中特别加以标注引用的内容外,本论文不包含任何其他个人或集体已经发表或撰写的成果作品。对本文的研究做出重要贡献的个人和集体,均已在文中以明确方式标明。本人完全意识到本声明的法律后果由本人承担。
作者签名: 日期:
学位论文版权使用授权书
本学位论文作者完全了解学校有关保留、使用学位论文的规定,同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。本人授权 大学可以将本学位论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。
涉密论文按学校规定处理。
作者签名: 日期:
导师签名: 日期:
Android平台中文输入法设计和实现
伴随着手持通信设备的日益普及和短信、微博等应用的广泛使用,人们越来越多地依赖于这些设备进行文字信息输入和处理。如何快速准确地利用手持式设备输入文字信息,特别是中文信息,对中国人而言有利于重要。
首先,本文介绍了Andriod的主要组件和系统框架等内容,并分析了当今移动平台上的主流汉字输入法
正在加载中,请稍后...输入法类 - Windows Mobile - 手机软件
当前位置: &
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile
适用机型:Windows Mobile13665人阅读
Android_APP(22)
输入法,就是用来输入字符(包括英文,俄文,中文)的工具。输入法你可以看成是一种字符发生器,它将输入数据触摸事件或者按键事件转化为其他更丰富的字符。在PC时代,输入法的原始输入来自实体键盘,鼠标,然后输入法将这些事件对应的ASCII码转换为俄文,中文,当然如果是英文是不需要转换,直接发送即可。而在Android系统里,由于输入法dialog永远没法成为焦点window,所以输入法永远没法获取到按键事件,也就是说输入法的输入数据只能来自触摸事件,输入法显示出键盘(大家称之为软键盘),用户点击键盘UI,
然后输入法将触摸事件所在位置的字符当做原始字符输入,最后组装成更为丰富的字符(多个字符组成拼音,然后转化为中文),然后就是发送到对应的程序。
&&&&&&& Android系统中,输入法可以是可以安装的,也就是说系统可以有多个输入法((sougou输入法,百度输入法),但是只有一个是激活的,当然用户可以切换输入法。同时,输入法是以service的方式运行的,输入法同一时间只能服务一个程序,只有最顶层的可见的程序才能接收到输入法的输入数据。
& & & &输入法系统的整个框架如下:
&&&& & InputMethodManagerService(下文也称IMMS)负责管理系统的所有输入法,包括输入法service(InputMethodService简称IMS)加载及切换。程序获得焦点时,就会通过InputMethodManager向InputMethodManagerService通知自己获得焦点并请求绑定自己到当前输入法上。同时,当程序的某个需要输入法的view比如EditorView获得焦点时就会通过InputMethodManager向InputMethodManagerService请求显示输入法,而这时InputMethodManagerService收到请求后,会将请求的EditText的数据通信接口发送给当前输入法,并请求显输入法。输入法收到请求后,就显示自己的UI
dialog,同时保存目标view的数据结构,当用户实现输入后,直接通过view的数据通信接口将字符传递到对应的View。接下来就来分析这些过程。
InputMethodManager创建
&&&&&&& 每个程序有一个InputMethodManager实例,这个是程序和InputMethodManagerService通信的接口,该实例在ViewRootImpl初始化的时候创建。
public&ViewRootImpl(Context&context,&Display&display)&{&&&&&&mContext&=&&&&&&&mWindowSession&=&WindowManagerGlobal.getWindowSession();&&}&&&&public&static&IWindowSession&getWindowSession()&{&&&&&&synchronized&(WindowManagerGlobal.class)&{&&&&&&&&&&if&(sWindowSession&==&null)&{&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&InputMethodManager&imm&=&InputMethodManager.getInstance();&&&&&&&&&&&&&&&&&&IWindowManager&windowManager&=&getWindowManagerService();&&&&&&&&&&&&&&}&catch&(RemoteException&e)&{&&&&&&&&&&&&&&&&&&Log.e(TAG,&&Failed&to&open&window&session&,&e);&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&&&&&return&sWindowS&&&&&&}&&}&&&&public&static&InputMethodManager&getInstance()&{&&&&&&synchronized&(InputMethodManager.class)&{&&&&&&&&&&if&(sInstance&==&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&IBinder&b&=&ServiceManager.getService(Context.INPUT_METHOD_SERVICE);&&&&&&&&&&&&&&IInputMethodManager&service&=&IInputMethodManager.Stub.asInterface(b);&&&&&&&&&&&&&&sInstance&=&new&InputMethodManager(service,&Looper.getMainLooper());&&&&&&&&&&}&&&&&&&&&&return&sI&&&&&&}&&}&&
程序的Window获得焦点
&&&&&&&&&&&程序的window获得焦点的时序图如下
系统WindowManagerService更新焦点window
&&&&&&&& 哪个程序获得焦点是由系统决定的,是由WindowManagerService决定的,当系统的window状态发生变化时(比如window新增,删除)就会调用函数updateFocusedWindowLocked来更新焦点window。
private&boolean&updateFocusedWindowLocked(int&mode,&boolean&updateInputWindows)&{&&&&&&&&&&&&WindowState&newFocus&=&computeFocusedWindowLocked();&&&&&&if&(mCurrentFocus&!=&newFocus)&{&&&&&&&&&&&&&&&&&&&&mH.removeMessages(H.REPORT_FOCUS_CHANGE);&&&&&&&&&&mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);&&&&&&&&&&return&true;&&&&&&}&&&&&&return&false;&&}&&&&private&WindowState&computeFocusedWindowLocked()&{&&&&&&if&(mAnimator.mUniverseBackground&!=&null&&&&&&&&&&&&&&&&&mAnimator.mUniverseBackground.mWin.canReceiveKeys())&{&&&&&&&&&&return&mAnimator.mUniverseBackground.mW&&&&&&}&&&&&&&&final&int&displayCount&=&mDisplayContents.size();&&&&&&for&(int&i&=&0;&i&&&displayC&i++)&{&&&&&&&&&&final&DisplayContent&displayContent&=&mDisplayContents.valueAt(i);&&&&&&&&&&WindowState&win&=&findFocusedWindowLocked(displayContent);&&&&&&&&&&if&(win&!=&null)&{&&&&&&&&&&&&&&return&&&&&&&&&&&}&&&&&&}&&&&&&return&null;&&}&&&&&&private&WindowState&findFocusedWindowLocked(DisplayContent&displayContent)&{&&&&&&final&WindowList&windows&=&displayContent.getWindowList();&&&&&&for&(int&i&=&windows.size()&-&1;&i&&=&0;&i--)&{&&&&&&&&&&final&WindowState&win&=&windows.get(i);&&&&&&&&&&&&&&&&&&&&AppWindowToken&wtoken&=&win.mAppT&&&&&&&&&&&&&&&&&&&&if&(!win.canReceiveKeys())&{&&&&&&&&&&&&&&continue;&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(wtoken&!=&null&&&&win.mAttrs.type&!=&TYPE_APPLICATION_STARTING&&&&&&&&&&&&&&&&&&&&&mFocusedApp&!=&null)&{&&&&&&&&&&&&&&ArrayList&Task&&tasks&=&displayContent.getTasks();&&&&&&&&&&&&&&for&(int&taskNdx&=&tasks.size()&-&1;&taskNdx&&=&0;&--taskNdx)&{&&&&&&&&&&&&&&&&&&AppTokenList&tokens&=&tasks.get(taskNdx).mAppT&&&&&&&&&&&&&&&&&&int&tokenNdx&=&tokens.size()&-&1;&&&&&&&&&&&&&&&&&&for&(&;&tokenNdx&&=&0;&--tokenNdx)&{&&&&&&&&&&&&&&&&&&&&&&final&AppWindowToken&token&=&tokens.get(tokenNdx);&&&&&&&&&&&&&&&&&&&&&&if&(wtoken&==&token)&{&&&&&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&if&(mFocusedApp&==&token)&{&&&&&&&&&&&&&&&&&&&&&&&&&&return&null;&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&&&&&return&&&&&&&}&&&&&&return&null;&&}&&&&public&final&boolean&canReceiveKeys()&{&&&&&&return&isVisibleOrAdding()&&&&&&&&&&&&&&&&&(mViewVisibility&==&View.VISIBLE)&&&&&&&&&&&&&&&&&((mAttrs.flags&&&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)&==&0);&&}&&&&&&&&final&class&H&extends&Handler&{&&&&&&@Override&&&&&&public&void&handleMessage(Message&msg)&{&&&&&&&&&&switch&(msg.what)&{&&&&&&&&&&&&&&case&REPORT_FOCUS_CHANGE:&{&&&&&&&&&&&&&&&&&&WindowState&lastF&&&&&&&&&&&&&&&&&&WindowState&newF&&&&&&&&&&&&&&&&&&&&synchronized(mWindowMap)&{&&&&&&&&&&&&&&&&&&&&&&lastFocus&=&mLastF&&&&&&&&&&&&&&&&&&&&&&newFocus&=&mCurrentF&&&&&&&&&&&&&&&&&&&&&&if&(lastFocus&==&newFocus)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return;&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&mLastFocus&=&newF&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&if&(newFocus&!=&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&newFocus.reportFocusChangedSerialized(true,&mInTouchMode);&&&&&&&&&&&&&&&&&&&&&&notifyFocusChanged();&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&if&(lastFocus&!=&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&lastFocus.reportFocusChangedSerialized(false,&mInTouchMode);&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&break;&&&}&&&&&public&void&reportFocusChangedSerialized(boolean&focused,&boolean&inTouchMode)&{&&&&&&try&{&&&&&&&&&&&&&&&&&&&&mClient.windowFocusChanged(focused,&inTouchMode);&&&&&&}&catch&(RemoteException&e)&{&&&&&&}&&}&&
&&&&&&& 上面的mClient.windowFocusChanged会调回到ViewRootImpl中的W实例:
程序获得焦点改变事件
&&&&&&&&&&&
&&static&class&W&extends&IWindow.Stub&{&&&&&&@Override&&&&&&public&void&windowFocusChanged(boolean&hasFocus,&boolean&inTouchMode)&{&&&&&&&&&&final&ViewRootImpl&viewAncestor&=&mViewAncestor.get();&&&&&&&&&&if&(viewAncestor&!=&null)&{&&&&&&&&&&&&&&viewAncestor.windowFocusChanged(hasFocus,&inTouchMode);&&&&&&&&&&}&&&&&&}&&&&&&public&void&windowFocusChanged(boolean&hasFocus,&boolean&inTouchMode)&{&&&&&&Message&msg&=&Message.obtain();&&&&&&msg.what&=&MSG_WINDOW_FOCUS_CHANGED;&&&&&&msg.arg1&=&hasFocus&?&1&:&0;&&&&&&msg.arg2&=&inTouchMode&?&1&:&0;&&&&&&mHandler.sendMessage(msg);&&}&&&&&&&&final&class&ViewRootHandler&extends&Handler&{&&&&&&@Override&&&&&&public&void&handleMessage(Message&msg)&{&&&&&&&&&&switch&(msg.what)&{&&&&&&&&&&case&MSG_WINDOW_FOCUS_CHANGED:&{&&&&&&&&&&&&&&if&(mAdded)&{&&&&&&&&&&&&&&&&&&boolean&hasWindowFocus&=&msg.arg1&!=&0;&&&&&&&&&&&&&&&&&&mAttachInfo.mHasWindowFocus&=&hasWindowF&&&&&&&&&&&&&&&&&&mLastWasImTarget&=&WindowManager.LayoutParams&&&&&&&&&&&&&&&&&&&&&&&&&&.mayUseInputMethod(mWindowAttributes.flags);&&&&&&&&&&&&&&&&&&InputMethodManager&imm&=&InputMethodManager.peekInstance();&&&&&&&&&&&&&&&&&&if&(mView&!=&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&mView.dispatchWindowFocusChanged(hasWindowFocus);&&&&&&&&&&&&&&&&&&&&&&mAttachInfo.mTreeObserver.dispatchOnWindowFocusChange(&&indowFocus);&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&if&(hasWindowFocus)&{&&&&&&&&&&&&&&&&&&&&&&if&(imm&!=&null&&&&mLastWasImTarget&&&&!isInLocalFocusMode())&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&imm.onWindowFocus(mView,&mView.findFocus(),&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&mWindowAttributes.softInputMode,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&!mHasHadWindowFocus,&mWindowAttributes.flags);&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&&&&&&&&&&&&}&break;&&}&&&&&&&&&&@Override&&public&void&dispatchWindowFocusChanged(boolean&hasFocus)&{&&&&&&super.dispatchWindowFocusChanged(hasFocus);&&&&&&final&int&count&=&mChildrenC&&&&&&final&View[]&children&=&mC&&&&&&&&&&&&&&&&&&for&(int&i&=&0;&i&&&&i++)&{&&&&&&&&&&children[i].dispatchWindowFocusChanged(hasFocus);&&&&&&}&&}&&&&&&public&void&onWindowFocusChanged(boolean&hasWindowFocus)&{&&&&&&InputMethodManager&imm&=&InputMethodManager.peekInstance();&&&&&&if&(!hasWindowFocus)&{&&&&&&}&else&if&(imm&!=&null&&&&(mPrivateFlags&&&PFLAG_FOCUSED)&!=&0)&{&&&&&&&&&&&&&&&&&&&&imm.focusIn(this);&&&&&&}&&}&&
焦点View向IMMS请求绑定输入法
&&&&&&&& 焦点view请求绑定输入法是通过调用InputMethodManager. focusIn实现的
public&void&focusIn(View&view)&{&&&&&&synchronized&(mH)&{&&&&&&&&&&focusInLocked(view);&&&&&&}&&}&&&&void&focusInLocked(View&view)&{&&&&&&&&&&&&&mNextServedView&=&&&&&&&scheduleCheckFocusLocked(view);&&}&&&&static&void&scheduleCheckFocusLocked(View&view)&{&&&&&&ViewRootImpl&viewRootImpl&=&view.getViewRootImpl();&&&&&&if&(viewRootImpl&!=&null)&{&&&&&&&&&&viewRootImpl.dispatchCheckFocus();&&&&&&}&&}&&&&public&void&dispatchCheckFocus()&{&&&&&&if&(!mHandler.hasMessages(MSG_CHECK_FOCUS))&{&&&&&&&&&&&&&&&&&&&&mHandler.sendEmptyMessage(MSG_CHECK_FOCUS);&&&&&&}&&}&&&&&&&&&&case&MSG_CHECK_FOCUS:&{&&&&&&&&&&&&&&InputMethodManager&imm&=&InputMethodManager.peekInstance();&&&&&&&&&&&&&&if&(imm&!=&null)&{&&&&&&&&&&&&&&&&&&imm.checkFocus();&&&&&&&&&&&&&&}&&&&&&&&&&}&break;&&&&public&void&checkFocus()&{&&&&&&if&(checkFocusNoStartInput(false,&true))&{&&&&&&&&&&startInputInner(null,&0,&0,&0);&&&&&&}&&}&&&&&&boolean&startInputInner(IBinder&windowGainingFocus,&int&controlFlags,&int&softInputMode,&&&&&&&&&&int&windowFlags)&{&&&&&&final&View&&&&&&&synchronized&(mH)&{&&&&&&&&&&&&&&&&&&&&view&=&mServedV&&&&&&}&&&&&&&&EditorInfo&tba&=&new&EditorInfo();&&&&&&tba.packageName&=&view.getContext().getPackageName();&&&&&&tba.fieldId&=&view.getId();&&&&&&&&&&&&&&&&&&InputConnection&ic&=&view.onCreateInputConnection(tba);&&&&&&&&&&&&synchronized&(mH)&{&&&&&&&&&&mServedInputConnection&=&&&&&&&&&&&ControlledInputConnectionWrapper&servedC&&&&&&&&&&if&(ic&!=&null)&{&&&&&&&&&&&&&&mCursorSelStart&=&tba.initialSelS&&&&&&&&&&&&&&mCursorSelEnd&=&tba.initialSelE&&&&&&&&&&&&&&mCursorCandStart&=&-1;&&&&&&&&&&&&&&mCursorCandEnd&=&-1;&&&&&&&&&&&&&&mCursorRect.setEmpty();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&servedContext&=&new&ControlledInputConnectionWrapper(vh.getLooper(),&ic,&this);&&&&&&&&&&}&&&&&&&&&&mServedInputConnectionWrapper&=&servedC&&&&&&&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&InputBindResult&&&&&&&&&&&&&&&if&(windowGainingFocus&!=&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&res&=&mService.windowGainedFocus(mClient,&windowGainingFocus,&&&&&&&&&&&&&&&&&&&&&&&&&&controlFlags,&softInputMode,&windowFlags,&&&&&&&&&&&&&&&&&&&&&&&&&&tba,&servedContext);&&&&&&&&&&&&&&}&else&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&res&=&mService.startInput(mClient,&&&&&&&&&&&&&&&&&&&&&&&&&&servedContext,&tba,&controlFlags);&&&&&&&&&&&&&&}&&&&&&&&&&&&&&if&(res&!=&null)&{&&&&&&&&&&&&&&&&&&if&(res.id&!=&null)&{&&&&&&&&&&&&&&&&&&&&&&setInputChannelLocked(res.channel);&&&&&&&&&&&&&&&&&&&&&&mBindSequence&=&res.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&mCurMethod&=&res.&&&&&&&&&&&&&&&&&&&&&&mCurId&=&res.&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&&&&&&&return&true;&&}&&
IMMS处理view绑定输入法事件
&&&&&&&& 为了讲解整个绑定过程,我们假设此时输入法service还没启动,这个情况下的输入法绑定是最长的,整个过程经历过如下过程:
1)&&&&&& 启动输入法service
2)&&&&&& 绑定输入法window的token
3)&&&&&& 请求输入法为焦点程序创建一个连接会话-
4)&&&&&& 将输入法的接口传递回程序client端
5)&&&&&& 绑定输入法和焦点view
&&&&&&&&& 1-4是和程序相关的,而5是和view相关的。所以你可以说1~4是用来绑定程序window和输入法,而5是用来绑定程序view和输入法。
&&&&&&&&& 输入法还没启动时,弹出输入法会经过1~5,输入法已经启动,但是焦点window发生变化时会经历3~5,焦点window没有变化,只是改变了焦点view,则只会经历5。整个流程如下:
启动输入法service
@Override&&public&InputBindResult&startInput(IInputMethodClient&client,&&&&&&&&&&IInputContext&inputContext,&EditorInfo&attribute,&int&controlFlags)&{&&&&&&synchronized&(mMethodMap)&{&&&&&&&&&&final&long&ident&=&Binder.clearCallingIdentity();&&&&&&&&&&try&{&&&&&&&&&&&&&&return&startInputLocked(client,&inputContext,&attribute,&controlFlags);&&&&&&&&&&}&&&&&&}&&}&&InputBindResult&startInputLocked(IInputMethodClient&client,&&&&&&&&&&IInputContext&inputContext,&EditorInfo&attribute,&int&controlFlags)&{&&&&&&&&&&&&ClientState&cs&=&mClients.get(client.asBinder());&&&&&&return&startInputUncheckedLocked(cs,&inputContext,&attribute,&controlFlags);&&}&&&&InputBindResult&startInputUncheckedLocked(ClientState&cs,&&&&&&&&&&IInputContext&inputContext,&EditorInfo&attribute,&int&controlFlags)&{&&&&&&&&&&&&if&(mCurClient&!=&cs)&{&&&&&&&&&&&&&&&&&&&&unbindCurrentClientLocked();&&&&&&}&&&&&&&&&&&&&&mCurClient&=&&&&&&&mCurInputContext&=&inputC&&&&&&mCurAttribute&=&&&&&&&&&if&(mCurId&!=&null&&&&mCurId.equals(mCurMethodId))&{&&&&&&&&&&if&(cs.curSession&!=&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&return&attachNewInputLocked(&&&&&&&&&&&&&&&&&&&&&&(controlFlags&InputMethodManager.CONTROL_START_INITIAL)&!=&0);&&&&&&&&&&}&&&&&&&&&&if&(mHaveConnection)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(mCurMethod&!=&null)&{&&&&&&&&&&&&&&&&&&requestClientSessionLocked(cs);&&&&&&&&&&&&&&&&&&return&new&InputBindResult(null,&null,&mCurId,&mCurSeq);&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&&&&&&&&&&&return&startInputInnerLocked();&&}&&&&InputBindResult&startInputInnerLocked()&{&&&&&&InputMethodInfo&info&=&mMethodMap.get(mCurMethodId);&&&&&&&&unbindCurrentMethodLocked(false,&true);&&&&&&&&&&&&&&mCurIntent&=&new&Intent(InputMethod.SERVICE_INTERFACE);&&&&&&mCurIntent.setComponent(info.getComponent());&&&&&&mCurIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,&&&&&&&&&&&&&&com.android.internal.R.string.input_method_binding_label);&&&&&&mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT,&PendingIntent.getActivity(&&&&&&&&&&&&&&mContext,&0,&new&Intent(Settings.ACTION_INPUT_METHOD_SETTINGS),&0));&&&&&&if&(bindCurrentInputMethodService(mCurIntent,&this,&Context.BIND_AUTO_CREATE&&&&&&&&&&&&&&|&Context.BIND_NOT_VISIBLE&|&Context.BIND_SHOWING_UI))&{&&&&&&&&&&mHaveConnection&=&true;&&&&&&&&&&mCurId&=&info.getId();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&mCurToken&=&new&Binder();&&&&&&&&&&try&{&&&&&&&&&&&&&&mIWindowManager.addWindowToken(mCurToken,&&&&&&&&&&&&&&&&&&&&&&WindowManager.LayoutParams.TYPE_INPUT_METHOD);&&&&&&&&&&}&catch&(RemoteException&e)&{&&&&&&&&&&}&&&&&&&&&&return&new&InputBindResult(null,&null,&mCurId,&mCurSeq);&&&&&&}&&&&&&return&null;&&}&&&&private&boolean&bindCurrentInputMethodService(&&&&&&&&&&Intent&service,&ServiceConnection&conn,&int&flags)&{&&&&&&if&(service&==&null&||&conn&==&null)&{&&&&&&&&&&Slog.e(TAG,&&---&bind&failed:&service&=&&&+&service&+&&,&conn&=&&&+&conn);&&&&&&&&&&return&false;&&&&&&}&&&&&&return&mContext.bindServiceAsUser(service,&conn,&flags,&&&&&&&&&&&&&&new&UserHandle(mSettings.getCurrentUserId()));&&}&&&&&&@Override&&final&public&IBinder&onBind(Intent&intent)&{&&&&&&if&(mInputMethod&==&null)&{&&&&&&&&&&mInputMethod&=&onCreateInputMethodInterface();&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&return&new&IInputMethodWrapper(this,&mInputMethod);&&}&&&&@Override&&public&AbstractInputMethodImpl&onCreateInputMethodInterface()&{&&&&&&return&new&InputMethodImpl();&&}&&&&&&&&&&@Override&&public&void&onServiceConnected(ComponentName&name,&IBinder&service)&{&&&&&&synchronized&(mMethodMap)&{&&&&&&&&&&if&(mCurIntent&!=&null&&&&name.equals(mCurIntent.getComponent()))&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&mCurMethod&=&IInputMethod.Stub.asInterface(service);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&executeOrSendMessage(mCurMethod,&mCaller.obtainMessageOO(&&&&&&&&&&&&&&&&&&&&&&MSG_ATTACH_TOKEN,&mCurMethod,&mCurToken));&&&&&&&&&&&&&&if&(mCurClient&!=&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&requestClientSessionLocked(mCurClient);&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&}&&
输入法Window token的绑定及使用分析
&&&&& 输入法Window token绑定
&&&&&&&&IMMS在输入法启动完成并回调onServiceConnected时会将一个Window token传递给输入法。
@Override&&public&void&onServiceConnected(ComponentName&name,&IBinder&service)&{&&&&&&synchronized&(mMethodMap)&{&&&&&&&&&&if&(mCurIntent&!=&null&&&&name.equals(mCurIntent.getComponent()))&{&&&&&&&&&&&&&&mCurMethod&=&IInputMethod.Stub.asInterface(service);&&&&&&&&&&&&&&executeOrSendMessage(mCurMethod,&mCaller.obtainMessageOO(&&&&&&&&&&&&&&&&&&&&&&MSG_ATTACH_TOKEN,&mCurMethod,&mCurToken));&&&&&&&&&&&&&&if&(mCurClient&!=&null)&{&&&&&&&&&&&&&&&&&&clearClientSessionLocked(mCurClient);&&&&&&&&&&&&&&&&&&requestClientSessionLocked(mCurClient);&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&}&&&&&&&&&&case&MSG_ATTACH_TOKEN:&&&&&&&&&&&&&&args&=&(SomeArgs)msg.&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&((IInputMethod)args.arg1).attachToken((IBinder)args.arg2);&&&&&&&&&&&&&&}&catch&(RemoteException&e)&{&&&&&&&&&&&&&&}&&&&&&&&&&&&&&args.recycle();&&&&public&class&InputMethodService&extends&AbstractInputMethodService&{&&public&class&InputMethodImpl&extends&AbstractInputMethodImpl&{&&&&&&public&void&attachToken(IBinder&token)&{&&&&&&&&&&if&(mToken&==&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&mToken&=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&mWindow.setToken(token);&&&&&&&&&&}&&&&&&}&&}&&
&&&&& 输入法Window token使用
& &&&& 由于系统存在多个输入法,所以输入法要和IMMS通信,必须要个机制来标示自己是哪个输入法,这个就是通过上面的输入法Window token来实现的,比如输入法自己关闭自己:
&&public&void&requestHideSelf(int&flags)&{&&&&&&&&&&&&mImm.hideSoftInputFromInputMethod(mToken,&flags);&&}&&&&public&void&hideSoftInputFromInputMethod(IBinder&token,&int&flags)&{&&&&&&try&{&&&&&&&&&&mService.hideMySoftInput(token,&flags);&&&&&&}&catch&(RemoteException&e)&{&&&&&&&&&&throw&new&RuntimeException(e);&&&&&&}&&}&&&&&&@Override&&public&void&hideMySoftInput(IBinder&token,&int&flags)&{&&&&&&if&(!calledFromValidUser())&{&&&&&&&&&&return;&&&&&&}&&&&&&synchronized&(mMethodMap)&{&&&&&&&&&&if&(token&==&null&||&mCurToken&!=&token)&{&&&&&&&&&&&&&&if&(DEBUG)&Slog.w(TAG,&&Ignoring&hideInputMethod&of&uid&&&&&&&&&&&&&&&&&&&&&&&&+&Binder.getCallingUid()&+&&&token:&&&+&token);&&&&&&&&&&&&&&return;&&&&&&&&&&}&&&&&&&&&&long&ident&=&Binder.clearCallingIdentity();&&&&&&&&&&try&{&&&&&&&&&&&&&&hideCurrentInputLocked(flags,&null);&&&&&&&&&&}&finally&{&&&&&&&&&&&&&&Binder.restoreCallingIdentity(ident);&&&&&&&&&&}&&&&&&}&&}&&
输入法连接会话创建
&&&&&& 到此程序和输入法的session就建立了
@Override&&public&void&onServiceConnected(ComponentName&name,&IBinder&service)&{&&&&&&synchronized&(mMethodMap)&{&&&&&&&&&&if&(mCurIntent&!=&null&&&&name.equals(mCurIntent.getComponent()))&{&&&&&&&&&&&&&&if&(mCurClient&!=&null)&{&&&&&&&&&&&&&&&&&&clearClientSessionLocked(mCurClient);&&&&&&&&&&&&&&&&&&requestClientSessionLocked(mCurClient);&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&}&&&&void&requestClientSessionLocked(ClientState&cs)&{&&&&&&if&(!cs.sessionRequested)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&InputChannel[]&channels&=&InputChannel.openInputChannelPair(cs.toString());&&&&&&&&&&cs.sessionRequested&=&true;&&&&&&&&&&executeOrSendMessage(mCurMethod,&mCaller.obtainMessageOOO(&&&&&&&&&&&&&&&&&&MSG_CREATE_SESSION,&mCurMethod,&channels[1],&&&&&&&&&&&&&&&&&&new&MethodCallback(this,&mCurMethod,&channels[0])));&&&&&&}&&&}&&&&&&&&&&case&MSG_CREATE_SESSION:&{&&&&&&&&&&&&&&args&=&(SomeArgs)msg.&&&&&&&&&&&&&&IInputMethod&method&=&(IInputMethod)args.arg1;&&&&&&&&&&&&&&InputChannel&channel&=&(InputChannel)args.arg2;&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&method.createSession(channel,&(IInputSessionCallback)args.arg3);&&&&&&&&&&&&&&}&catch&(RemoteException&e)&{&&&&&&&&&&&&&&}&&&&&public&abstract&class&AbstractInputMethodService&extends&Service&&&&&&implements&KeyEvent.Callback&{&&&public&abstract&class&AbstractInputMethodImpl&implements&InputMethod&{&&&&&&public&void&createSession(SessionCallback&callback)&{&&&&&&&&&&callback.sessionCreated(onCreateInputMethodSessionInterface());&&&&&&}&&pre&class=&java&&name=&code&&&&&&&}&&
} @Override public AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface() { //sesion的真正实现 return new InputMethodSessionImpl(); } //然后回到了IMMS void onSessionCreated(IInputMethod method, IInputMethodSession session, InputChannel channel) { synchronized
(mMethodMap) { if (mCurMethod != null && method != null && mCurMethod.asBinder() == method.asBinder()) { if (mCurClient != null) { //将session相关的数据封装到SessionState对象里 mCurClient.curSession = new SessionState(mCurClient, method, session, channel); //这个会开始真正的绑定
InputBindResult res = attachNewInputLocked(true); } } } }
传递输入法接口给程序
void&onSessionCreated(IInputMethod&method,&IInputMethodSession&session,&&&&&&&&&&InputChannel&channel)&{&&&&&&synchronized&(mMethodMap)&{&&&&&&&&&&if&(mCurMethod&!=&null&&&&method&!=&null&&&&&&&&&&&&&&&&&&&&&mCurMethod.asBinder()&==&method.asBinder())&{&&&&&&&&&&&&&&if&(mCurClient&!=&null)&{&&&&&&&&&&&&&&&&&&InputBindResult&res&=&attachNewInputLocked(true);&&&&&&&&&&&&&&&&&&if&(res.method&!=&null)&{&&&&&&&&&&&&&&&&&&&&&&executeOrSendMessage(mCurClient.client,&mCaller.obtainMessageOO(&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&MSG_BIND_METHOD,&mCurClient.client,&res));&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&return;&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&&&&&channel.dispose();&&}&&&&&&&&&&case&MSG_BIND_METHOD:&{&&&&&&&&&&&&&&args&=&(SomeArgs)msg.&&&&&&&&&&&&&&IInputMethodClient&client&=&(IInputMethodClient)args.arg1;&&&&&&&&&&&&&&InputBindResult&res&=&(InputBindResult)args.arg2;&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&client.onBindMethod(res);&&&&&&&&&&&&&&}&&&&&&&&&&&&&&args.recycle();&&&&&&&&&&&&&&return&true;&&&&&&&&&&}&&
输入法和view绑定
&&InputBindResult&attachNewInputLocked(boolean&initial)&{&&&&&&&if&(!mBoundToMethod)&{&&&&&&&&&&&executeOrSendMessage(mCurMethod,&mCaller.obtainMessageOO(&&&&&&&&&&&&&&&&&&&MSG_BIND_INPUT,&mCurMethod,&mCurClient.binding));&&&&&&&&&&&mBoundToMethod&=&true;&&&&&&&}&&&&&&&final&SessionState&session&=&mCurClient.curS&&&&&&&if&(initial)&{&&&&&&&&&&&executeOrSendMessage(session.method,&mCaller.obtainMessageOOO(&&&&&&&&&&&&&&&&&&&MSG_START_INPUT,&session,&mCurInputContext,&mCurAttribute));&&&&&&&}&else&{&&&&&&&&&&&executeOrSendMessage(session.method,&mCaller.obtainMessageOOO(&&&&&&&&&&&&&&&&&&&MSG_RESTART_INPUT,&session,&mCurInputContext,&mCurAttribute));&&&&&&&}&&&&&&&return&new&InputBindResult(session.session,&&&&&&&&&&&&&&&session.channel&!=&null&?&session.channel.dup()&:&null,&mCurId,&mCurSeq);&&&}&&&&&&&&&&&case&MSG_BIND_INPUT:&&&&&&&&&&&&&&&args&=&(SomeArgs)msg.&&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&&((IInputMethod)args.arg1).bindInput((InputBinding)args.arg2);&&&&&&&&&&&&&&&}&catch&(RemoteException&e)&{&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&args.recycle();&&&&&&&&&&&&&&&return&true;&&&&&&&&&&&&&&&&&&&&&case&MSG_START_INPUT:&&&&&&&&&&&&&&&args&=&(SomeArgs)msg.&&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&&SessionState&session&=&(SessionState)args.arg1;&&&&&&&&&&&&&&&&&&&session.method.startInput((IInputContext)args.arg2,&&&&&&&&&&&&&&&&&&&&&&&&&&&(EditorInfo)args.arg3);&&&&&&&&&&&&&&&}&catch&(RemoteException&e)&{&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&args.recycle();&&&&&&&&&&&&&&&return&true;&&&&&&@Override&&&public&void&startInput(IInputContext&inputContext,&EditorInfo&attribute)&{&&&&&&&mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_START_INPUT,&&&&&&&&&&&&&&&inputContext,&attribute));&&&}&&&&&&&&&&&case&DO_START_INPUT:&{&&&&&&&&&&&&&&&SomeArgs&args&=&(SomeArgs)msg.&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&IInputContext&inputContext&=&(IInputContext)args.arg1;&&&&&&&&&&&&&&&InputConnection&ic&=&inputContext&!=&null&&&&&&&&&&&&&&&&&&&&&&&?&new&InputConnectionWrapper(inputContext)&:&null;&&&&&&&&&&&&&&&EditorInfo&info&=&(EditorInfo)args.arg2;&&&&&&&&&&&&&&&inputMethod.startInput(ic,&info);&&&&&&&&&&&&&&&args.recycle();&&&&&&&&&&&&&&&return;&&&&&&&&&&&}&&&public&class&InputMethodImpl&extends&AbstractInputMethodImpl&{&&&&&&&public&void&startInput(InputConnection&ic,&EditorInfo&attribute)&{&&&&&&&&&&&doStartInput(ic,&attribute,&false);&&&&&&&}&&&}&&&&&void&doStartInput(InputConnection&ic,&EditorInfo&attribute,&boolean&restarting)&{&&&&&&&if&(!restarting)&{&&&&&&&&&&&doFinishInput();&&&&&&&}&&&&&&&mInputStarted&=&true;&&&&&&&mStartedInputConnection&=&&&&&&&&mInputEditorInfo&=&&&&&&&&initialize();&&&&&&&onStartInput(attribute,&restarting);&&&&&&&if&(mWindowVisible)&{&&&&&&&&&&&if&(mShowInputRequested)&{&&&&&&&&&&&&&&&mInputViewStarted&=&true;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&onStartInputView(mInputEditorInfo,&restarting);&&&&&&&&&&&&&&&startExtractingText(true);&&&&&&&&&&&}&else&if&(mCandidatesVisibility&==&View.VISIBLE)&{&&&&&&&&&&&&&&&mCandidatesViewStarted&=&true;&&&&&&&&&&&&&&&onStartCandidatesView(mInputEditorInfo,&restarting);&&&&&&&&&&&}&&&&&&&}&&&}&&
&&&&&&& 到此焦点view已经通过调用IMMS的startInput和输入法绑定了,但是此时输入法还没有显示。但是系统紧接着会调用windowGainFocus来显示输入法。
程序焦点获取事件导致输入法显示
& & & &请查看输入法框架下篇
输入法响应显示请求
& & & &请查看输入法框架下篇
用户单击输入框View导致输入法显示
& & & &请查看输入法框架下篇
输入法传递输入文本信息给view
& & & &请查看输入法框架下篇
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:806095次
积分:8762
积分:8762
排名:第1762名
原创:135篇
转载:77篇
译文:13篇
评论:114条
(1)(9)(1)(3)(2)(13)(11)(9)(6)(8)(8)(6)(5)(14)(28)(89)(6)(1)(2)(2)(1)}

我要回帖

更多关于 搜狗输入法英文联想 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信