网站文档怎么加图片不显示不出来,免费浪漫网页制作网站,黑帽seo365t技术,专业建设 验收 网站前面说到#xff0c;应用程序添加窗口时#xff0c;会在本地创建一个ViewRoot#xff0c;然后通过IPC(进程间通信)调用WmS的Session的addWindow请求WmS创建窗口#xff0c;下面来看看addWindow方法。addWindow方法定义在frameworks/base/services/java/com.android.server.…前面说到应用程序添加窗口时会在本地创建一个ViewRoot然后通过IPC(进程间通信)调用WmS的Session的addWindow请求WmS创建窗口下面来看看addWindow方法。addWindow方法定义在frameworks/base/services/java/com.android.server.WindowManagerService.java中其代码如下所示public int addWindow(Session session, IWindow client,WindowManager.LayoutParams attrs, int viewVisibility,Rect outContentInsets, InputChannel outInputChannel) {// 是否有添加权限int res  mPolicy.checkAddPermission(attrs);if (res ! WindowManagerImpl.ADD_OKAY) {return res;}boolean reportNewConfig  false;WindowState attachedWindow  null;WindowState win  null;synchronized(mWindowMap) {// Instantiating a Display requires talking with the simulator,// so dont do it until we know the system is mostly up and// running.// 是否存在显示设置if (mDisplay  null) {// 若不存在则获取系统设置WindowManager wm  (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);mDisplay  wm.getDefaultDisplay();mInitialDisplayWidth  mDisplay.getWidth();mInitialDisplayHeight  mDisplay.getHeight();// 将Display存放到InputManager中mInputManager.setDisplaySize(0, mInitialDisplayWidth, mInitialDisplayHeight);reportNewConfig  true;}// 是否重复添加if (mWindowMap.containsKey(client.asBinder())) {Slog.w(TAG, Window   client   is already added);return WindowManagerImpl.ADD_DUPLICATE_ADD;}// 是否子窗口if (attrs.type  FIRST_SUB_WINDOW  attrs.type  LAST_SUB_WINDOW) {// 若为子窗口// 返回WmS中存在的对应父窗口若不存在则返回nullattachedWindow  windowForClientLocked(null, attrs.token, false);// 若父窗口不存在则表示添加了错误的子窗口if (attachedWindow  null) {Slog.w(TAG, Attempted to add window with token that is not a window:  attrs.token  . Aborting.);return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;}// 若取得的父窗口也是子窗口则表示添加了错误的子窗口从这里来看貌似窗口只有两层if (attachedWindow.mAttrs.type  FIRST_SUB_WINDOW attachedWindow.mAttrs.type  LAST_SUB_WINDOW) {Slog.w(TAG, Attempted to add window with token that is a sub-window:  attrs.token  . Aborting.);return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;}}boolean addToken  false;// 在WmS中寻找对应的WindowTokenWindowToken token  mTokenMap.get(attrs.token);if (token  null) {if (attrs.type  FIRST_APPLICATION_WINDOW attrs.type  LAST_APPLICATION_WINDOW) {// 对于子窗口来说WmS中必须有对应的Token才能添加Slog.w(TAG, Attempted to add application window with unknown token  attrs.token  . Aborting.);return WindowManagerImpl.ADD_BAD_APP_TOKEN;}if (attrs.type  TYPE_INPUT_METHOD) {// 如果是内置的输入方法窗口WmS中必须有对应的Token才能添加Slog.w(TAG, Attempted to add input method window with unknown token  attrs.token  . Aborting.);return WindowManagerImpl.ADD_BAD_APP_TOKEN;}if (attrs.type  TYPE_WALLPAPER) {// 墙纸窗口WmS中必须有对应的Token才能添加Slog.w(TAG, Attempted to add wallpaper window with unknown token  attrs.token  . Aborting.);return WindowManagerImpl.ADD_BAD_APP_TOKEN;}// 创建窗口token  new WindowToken(attrs.token, -1, false);addToken  true;} else if (attrs.type  FIRST_APPLICATION_WINDOW attrs.type  LAST_APPLICATION_WINDOW) {// token不为null且是应用窗口AppWindowToken atoken  token.appWindowToken;if (atoken  null) {// appWindowToken值不能为空Slog.w(TAG, Attempted to add window with non-application token  token  . Aborting.);return WindowManagerImpl.ADD_NOT_APP_TOKEN;} else if (atoken.removed) {// 试图使用存在的应用token添加窗口Slog.w(TAG, Attempted to add window with exiting application token  token  . Aborting.);return WindowManagerImpl.ADD_APP_EXITING;}if (attrs.type  TYPE_APPLICATION_STARTING  atoken.firstWindowDrawn) {// No need for this guy!// 窗口类型不能是应用启动时显示的窗口if (localLOGV) Slog.v(TAG, **** NO NEED TO START:   attrs.getTitle());return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;}} else if (attrs.type  TYPE_INPUT_METHOD) {// 对于内置的输入方法窗口token的windowType值要等于TYPE_INPUT_METHODif (token.windowType ! TYPE_INPUT_METHOD) {Slog.w(TAG, Attempted to add input method window with bad token  attrs.token  . Aborting.);return WindowManagerImpl.ADD_BAD_APP_TOKEN;}} else if (attrs.type  TYPE_WALLPAPER) {// 对于墙纸窗口token的windowType值要等于TYPE_WALLPAPERif (token.windowType ! TYPE_WALLPAPER) {Slog.w(TAG, Attempted to add wallpaper window with bad token  attrs.token  . Aborting.);return WindowManagerImpl.ADD_BAD_APP_TOKEN;}}// 创建窗口win  new WindowState(session, client, token,attachedWindow, attrs, viewVisibility);if (win.mDeathRecipient  null) {// Client has apparently died, so there is no reason to// continue.// 客户端已被销毁所以没必要继续Slog.w(TAG, Adding window client   client.asBinder()  that is dead, aborting.);return WindowManagerImpl.ADD_APP_EXITING;}// 如果是Toast则此窗口不能够接收input事件mPolicy.adjustWindowParamsLw(win.mAttrs);// 判断添加的窗口是单例还是多例res  mPolicy.prepareAddWindowLw(win, attrs);if (res ! WindowManagerImpl.ADD_OKAY) {// 是多例则直接返回return res;}// 如果输出的Channel也即Pipe中的读通道为空if (outInputChannel ! null) {// 创建通道String name  win.makeInputChannelName();InputChannel[] inputChannels  InputChannel.openInputChannelPair(name);win.mInputChannel  inputChannels[0];inputChannels[1].transferToBinderOutParameter(outInputChannel);// 在InputManager中注册通道mInputManager.registerInputChannel(win.mInputChannel);}// From now on, no exceptions or errors allowed!res  WindowManagerImpl.ADD_OKAY;// 重置当前线程的IPC的IDfinal long origId  Binder.clearCallingIdentity();// 从上述代码中得出是否要添加Token若是则添加Token添加到WmS中if (addToken) {mTokenMap.put(attrs.token, token);mTokenList.add(token);}// 将窗口添加到Session中win.attach();// 窗口信息添加到WmS中mWindowMap.put(client.asBinder(), win);if (attrs.type  TYPE_APPLICATION_STARTING token.appWindowToken ! null) {// 对于应用启动时显示的窗口设置tokentoken.appWindowToken.startingWindow  win;}boolean imMayMove  true;if (attrs.type  TYPE_INPUT_METHOD) {// 内置的输入方法窗口mInputMethodWindow  win;addInputMethodWindowToListLocked(win);imMayMove  false;} else if (attrs.type  TYPE_INPUT_METHOD_DIALOG) {// 内置的输入方法对话框窗口mInputMethodDialogs.add(win);addWindowToListInOrderLocked(win, true);adjustInputMethodDialogsLocked();imMayMove  false;} else {// 其他窗口addWindowToListInOrderLocked(win, true);if (attrs.type  TYPE_WALLPAPER) {mLastWallpaperTimeoutTime  0;adjustWallpaperWindowsLocked();} else if ((attrs.flagsFLAG_SHOW_WALLPAPER) ! 0) {adjustWallpaperWindowsLocked();}}win.mEnterAnimationPending  true;// 获取系统窗口区域的insetsmPolicy.getContentInsetHintLw(attrs, outContentInsets);if (mInTouchMode) {// 用户直接触摸的窗口res | WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;}if (win  null || win.mAppToken  null || !win.mAppToken.clientHidden) {// 应用窗口res | WindowManagerImpl.ADD_FLAG_APP_VISIBLE;}boolean focusChanged  false;if (win.canReceiveKeys()) {// 窗口需要按键事件// 更新焦点将窗口信息写入了InputDispatcherfocusChanged  updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);if (focusChanged) {imMayMove  false;}}if (imMayMove) {// 若需要锁定的话移动输入方法窗口moveInputMethodWindowsIfNeededLocked(false);}assignLayersLocked();// Dont do layout here, the window must call// relayout to be displayed, so well do it there.//dump();if (focusChanged) {finishUpdateFocusedWindowAfterAssignLayersLocked();}if (localLOGV) Slog.v(TAG, New client   client.asBinder() : window  win);if (win.isVisibleOrAdding()  updateOrientationFromAppTokensLocked()) {reportNewConfig  true;}}// sendNewConfiguration() checks caller permissions so we must call it with// privilege. updateOrientationFromAppTokens() clears and resets the caller// identity anyway, so its safe to just clear  restore around this whole// block.final long origId  Binder.clearCallingIdentity();if (reportNewConfig) {sendNewConfiguration();}Binder.restoreCallingIdentity(origId);return res;}有些东西还没摸明白后面深入学习后再补一下。上文还说到addWindow会将窗口信息写入InputDispatcher其实在addWindow代码中有体现if (win.canReceiveKeys()) {// 窗口需要按键事件// 更新焦点在这里将窗口信息写入了InputDispatcherfocusChanged  updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS);if (focusChanged) {imMayMove  false;}}         至于如何写入InputDispatcher下文分析。