当前位置: 首页 > wzjs >正文

做网站su饿了吗网站wordpress

做网站su,饿了吗网站wordpress,定制网站开发接活,优化前网站现状分析概述 本文主要讲述Android 系统创建窗口时与输入管理系统服务通过InputChannel通道建立通信桥梁的过程。 本文涉及的源码路径 frameworks/native/libs/input/InputTransport.cpp frameworks/base/core/java/android/view/InputChannel.java frameworks/base/core/java/andr…

概述

        本文主要讲述Android 系统创建窗口时与输入管理系统服务通过InputChannel通道建立通信桥梁的过程。

本文涉及的源码路径

frameworks/native/libs/input/InputTransport.cpp

frameworks/base/core/java/android/view/InputChannel.java

frameworks/base/core/java/android/view/ViewRootImpl.java

frameworks/base/core/jni/android_view_InputChannel.cpp

frameworks/base/core/jni/com_android_server_input_InputManagerService.cpp

frameworks/base/services/core/java/com/android/server/wm/Session.java

frameworks/base/core/java/android/view/WindowState.java

App创建InputChannel

        关于Android系统中的窗口与窗口视图相关的内容,我们有机会再进行讲述,我这里只描述创建视图时与输入相关的部分。方法是setView, 如下所示:

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {synchronized (this) {......// 如果窗口可接受输入事件,创建InputChannel输入通道if ((mWindowAttributes.inputFeatures& WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {mInputChannel = new InputChannel();}mForceDecorViewVisibility = (mWindowAttributes.privateFlags& PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;try {......res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,getHostVisibility(), mDisplay.getDisplayId(),mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,mAttachInfo.mOutsets, mInputChannel);} catch (RemoteException e) {......} finally {if (restore) {attrs.restore();}}......if (mInputChannel != null) {if (mInputQueueCallback != null) {mInputQueue = new InputQueue();mInputQueueCallback.onInputQueueCreated(mInputQueue);}mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,Looper.myLooper());}......}}}

setView方法关于属于的主要逻辑如下:

1、创建一个空的InputChannel通道;

2、mWindowSession.addToDisplay中对InputChannel进行初始化;

3、注册App窗口收到InputChannel通道数据的事件回调;

InputChannel通道的真正初始化由mWindowSession.addToDisplay完成,mWindowSession是IWindowSession,属于AIDL的服务代理端,它最终调用的是IWindowSession中的服务实现端,IWinodwSession由Session实现如下所示:

final class Session extends IWindowSession.Stub {@Overridepublic int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets,Rect outOutsets, InputChannel outInputChannel) {return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,outContentInsets, outStableInsets, outOutsets, outInputChannel);}
}

然后进一步调用了mService.addWindow, 而mService是WindowManagerService系统服务。因此mWindowSession.addToDisplay通过层层调用,最终调用到了WindowManagerService中的addWindow完成App和Input系统服务建立连接,如下所示:

public int addWindow(Session session, IWindow client, int seq,WindowManager.LayoutParams attrs, int viewVisibility, int displayId,Rect outContentInsets, Rect outStableInsets, Rect outOutsets,InputChannel outInputChannel) {......WindowState win = new WindowState(this, session, client, token,attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);if (win.mDeathRecipient == null) {// Client has apparently died, so there is no reason to// continue.Slog.w(TAG_WM, "Adding window client " + client.asBinder()+ " that is dead, aborting.");return WindowManagerGlobal.ADD_APP_EXITING;}if (win.getDisplayContent() == null) {Slog.w(TAG_WM, "Adding window to Display that has been removed.");return WindowManagerGlobal.ADD_INVALID_DISPLAY;}mPolicy.adjustWindowParamsLw(win.mAttrs);win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));res = mPolicy.prepareAddWindowLw(win, attrs);if (res != WindowManagerGlobal.ADD_OKAY) {return res;}final boolean openInputChannels = (outInputChannel != null&& (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);if  (openInputChannels) {win.openInputChannel(outInputChannel);}return res;}

这部分的代码涉及的内容比较复杂,我们只保留与窗口输入相关的部分,从代码中可以看到,由WindowState.openInputChannel方法进一步完成InputChannel的初始化,代码如下所示:

WindowState.java

 void openInputChannel(InputChannel outInputChannel) {if (mInputChannel != null) {throw new IllegalStateException("Window already has an input channel.");}String name = makeInputChannelName();InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);mInputChannel = inputChannels[0];mClientChannel = inputChannels[1];mInputWindowHandle.inputChannel = inputChannels[0];if (outInputChannel != null) {// 将mClientChannel的native对象绑定到outInputChannel的native对象mClientChannel.transferTo(outInputChannel);// 删除mClientChannel自己的native对象mClientChannel.dispose();mClientChannel = null;} else {// If the window died visible, we setup a dummy input channel, so that taps// can still detected by input monitor channel, and we can relaunch the app.// Create dummy event receiver that simply reports all events as handled.mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel);}mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle);}

该方法的主要逻辑如下:

1、App 创建Inputchannel通道, 用自己Client的InutChannel[0],初始化outputChannel通道;

2、将InutChannel[1] 注册到input系统服务中的InputDispatcher中;

注册服务端InputChannel到InputDispatcher

        上一章节,我们讲述了App创建输入通道的过程,本章节我们讲述App如何与input系统服务建立通信的桥梁的过程。建立的过程,我们可以把它抽象成linux中pipe管道,一端为App所持有outChannel,另外一端inputChannels[1]通过,mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle)的注册,让input系统服务持有。主要实现是通过调用InputManagerService中的registerInputChannel,如下所示:

 public void registerInputChannel(InputChannel inputChannel,InputWindowHandle inputWindowHandle) {if (inputChannel == null) {throw new IllegalArgumentException("inputChannel must not be null.");}nativeRegisterInputChannel(mPtr, inputChannel, inputWindowHandle, false);}

该方法进一步直接调用nativeRegisterInputChannel JNI方法如下所示:

static void nativeRegisterInputChannel(JNIEnv* env, jclass /* clazz */,jlong ptr, jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);......sp<InputWindowHandle> inputWindowHandle =android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);status_t status = im->registerInputChannel(env, inputChannel, inputWindowHandle, monitor);if (status) {String8 message;message.appendFormat("Failed to register input channel.  status=%d", status);jniThrowRuntimeException(env, message.string());return;}......
}

然后继续追踪,最终调用到了我们熟悉的InputDispatcher中的registerInputChannel,如下所示:

status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {......    { // acquire lockAutoMutex _l(mLock);sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);int fd = inputChannel->getFd();mConnectionsByFd.add(fd, connection);mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);} // release lock// Wake the looper because some connections have changed.mLooper->wake();return OK;
}

该方法的实现逻辑如下:

1、为每一个请求注册Inputchannel创建一个Connection进行管理,并将待注册的InputChannel的通道描述符和Connection建立关联容器映射;

2、将注册的InputChannel通道加入到InputDispatcher中Looper事件监控,当App向客户端的InputChannel写入信息时,则触发InputDispatcher中的handleReceiveCallback回调方法的调用,关于App和Input系统服务的通信过程,我们后续的章节进行讲述。

App注册事件回调

上一个章节,我们讲述了App和input系统服务建立通信连接的过程,那InputDispatcher发送msg时,App如何接收呢,核心实现如下所示:

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {.......if (mInputChannel != null) {if (mInputQueueCallback != null) {mInputQueue = new InputQueue();mInputQueueCallback.onInputQueueCreated(mInputQueue);}mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,Looper.myLooper());}
}

当InputDispacther向InputChannel写入事件信息时,App最终通过WindowInputEventReceiver进行事件的处理,App接受input事件和处理流程我们在下一篇进行讲述。

总结

        本文主要讲述了App初始化创建窗口时的与输入管理相关的处理流程,App为了能接收到系统上报的输入事件,通过InputChannel作为桥梁,将App和Input系统服务建立了通信桥梁,实现的核心原理就是创建socket对,并通过事件监听的方式,从socket中获取监听的信息,并进行处理,当App处理完信息也则通过socket对,告诉input系统服务的处理结果。后续章节我们会讲述这个处理流程。


文章转载自:

http://eI5JHKFF.mcbpc.cn
http://FSvEE8U6.mcbpc.cn
http://VPpWfkdY.mcbpc.cn
http://7TlNj75g.mcbpc.cn
http://9cUy69fe.mcbpc.cn
http://8X020NyX.mcbpc.cn
http://GtREDaJ8.mcbpc.cn
http://ij5TaBiw.mcbpc.cn
http://po8GuVgi.mcbpc.cn
http://cw80oYIE.mcbpc.cn
http://CKgF2jAM.mcbpc.cn
http://SBUoAOkR.mcbpc.cn
http://VOqoFjk3.mcbpc.cn
http://iWy4B2zx.mcbpc.cn
http://uMNtIT7t.mcbpc.cn
http://whqjks1c.mcbpc.cn
http://fIgHWXOP.mcbpc.cn
http://RnMHEqDB.mcbpc.cn
http://N1sTxzjY.mcbpc.cn
http://hzjWYG5z.mcbpc.cn
http://WnVI2Ccb.mcbpc.cn
http://ShrYhWaH.mcbpc.cn
http://a1Jl6T5f.mcbpc.cn
http://suTfSmv9.mcbpc.cn
http://cfMoYKG8.mcbpc.cn
http://jqlSn0Ay.mcbpc.cn
http://sLIwGpIh.mcbpc.cn
http://YkaGiGcl.mcbpc.cn
http://eyq2sDg3.mcbpc.cn
http://OBTgfkpm.mcbpc.cn
http://www.dtcms.com/wzjs/641284.html

相关文章:

  • 安徽建站之星网站开发框架具体是什么
  • 类似好123门户网站开发复杂么soho hotel 酒店 wordpress主题
  • 网页设计中好的网站二级域名wordpress
  • 重庆大足网站制作公司网站3网合一是怎么做的
  • 大连网站制作网页谷歌网站流量分析
  • 服装设计类网站有的网站无法打开
  • 网站建设是半年的持久战火车头 wordpress 4.9
  • 做网站和做网店哪个好seo在线优化系统
  • 网站建设与管理教案怎么写找项目
  • 做魔方网站用什么背景最好秦皇岛微信群
  • 阿卯网站建设网址查询服务中心
  • 杭州网站建设推广台州企业网站seo
  • php和html5做网站上海的建设网站制作
  • 建筑建设规范网站百度seo一本通
  • 做集团网站的深圳公司官网设计
  • 包头 网站制作上网建站
  • 团队做网站的收获儿童摄影网站设计
  • 如何建立一个网站详细步骤广州做餐饮的招聘网站
  • 公司网站的后台别墅效果图网站
  • 网站设计什么价位家纺 网站建设 中企动力
  • 常州商城网站建设承德名城建设集团网站
  • 思明自助建站软件wordpress 分类 seo
  • 中小企业网站建设资讯做邮轮的网站
  • wordpress移动到回收站时发生错误.成都私人网站制作公司
  • 生物网站模板中国建设工程造价管理协会
  • 番禺网站建设哪里有网站的建设维护
  • 公司网站界面设计哈尔滨网络推广优化
  • 什么是网站结构营销型网站建设的价格
  • 北京做网站推广兼职河南seo网站策划
  • 蚌埠网站制作公司价格网站建设价格女