Android的Window底层原理

1.概述 

Window是一个抽象类,他的实现是PhoneWindow。Window通过WindowManager创建,是访问Window的入口。Window的具体实现位于WindowManagerService中,WIndowManager与WindowManagerService的交互是一个IPC的过程。
WindowManager中的Layoutparam中的Type表示Window的类型,Window有三种类型,分别是应用Window、子Window和系统Window。应用类Window对应着一个Activity。子Window不能单独存在,他需要附属在特定的父Window,例如Dialog。系统Window是需要在声明权限在能创建Window,比如Toast。
Window的层级范围是1-99,子Window的层级范围是1000-1999,系统Window的层级范围是2000-2999。对应着LayoutParams的type参数。层级大的会覆盖在层级小的Window上面。
Layoutparams
  public static final int FIRST_SUB_WINDOW = 1000;
  public static final int FIRST_SYSTEM_WINDOW = 2000;

2.Window的内部实现机制

2.1Window、PhoneWindow、DecorView



window是一个抽象类,提供一组通用的绘制窗口API,可抽象理解为一个载体,各种View在这个载体上显示
PhoneWindow是window类的实现,类内部包含一个DecorView,
DecorView是一个FragmeLayout的子类,该DecorView对象时所有应用窗口的根View
Activity的setContentView调用到PhoneView的setConteView,如果没有DecorView,那么就创建他,将View添加到DecorView的mContentParent中,回调Activity的onContentChanged方法通知Activity视图已经发生改变
  
@Override
  public void setContentView(int layoutResID) {
  // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
  // decor, when theme attributes and the like are crystalized. Do not check the feature
  // before this happens.
  if (mContentParent == null) {
  installDecor();//创建DecorView
  } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {//所以Activity可以多次的setContetView-
  mContentParent.removeAllViews();
  }

  if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
  final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
  getContext());
  transitionTo(newScene);
  } else {
  mLayoutInflater.inflate(layoutResID, mContentParent);
  }
  mContentParent.requestApplyInsets();
  final Callback cb = getCallback();
  if (cb != null && !isDestroyed()) {
  cb.onContentChanged();
  }
  }

  private void installDecor() {
  if (mDecor == null) {
  mDecor = generateDecor();
  mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
  mDecor.setIsRootNamespace(true);
  if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
  mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
  }
  }
  if (mContentParent == null) {
  mContentParent = generateLayout(mDecor);

  // Set up decor part of UI to ignore fitsSystemWindows if appropriate.
  mDecor.makeOptionalFitsSystemWindows();

  final DecorContentParent decorContentParent = (DecorContentParent) mDecor.findViewById(
  R.id.decor_content_parent);

  if (decorContentParent != null) {
  mDecorContentParent = decorContentParent;
  mDecorContentParent.setWindowCallback(getCallback());
  if (mDecorContentParent.getTitle() == null) {
  mDecorContentParent.setWindowTitle(mTitle);
  }

  final int localFeatures = getLocalFeatures();
  for (int i = 0; i < FEATURE_MAX; i++) {
  if ((localFeatures & (1 << i)) != 0) {
  mDecorContentParent.initFeature(i);
  }
  }

  mDecorContentParent.setUiOptions(mUiOptions);

  if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0 ||
  (mIconRes != 0 && !mDecorContentParent.hasIcon())) {
  mDecorContentParent.setIcon(mIconRes);
  } else if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) == 0 &&
  mIconRes == 0 && !mDecorContentParent.hasIcon()) {
  mDecorContentParent.setIcon(
  getContext().getPackageManager().getDefaultActivityIcon());
  mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON_FALLBACK;
  }
  if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0 ||
  (mLogoRes != 0 && !mDecorContentParent.hasLogo())) {
  mDecorContentParent.setLogo(mLogoRes);
  }

  // Invalidate if the panel menu hasn't been created before this.
  // Panel menu invalidation is deferred avoiding application onCreateOptionsMenu
  // being called in the middle of onCreate or similar.
  // A pending invalidation will typically be resolved before the posted message
  // would run normally in order to satisfy instance state restoration.
  PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
  if (!isDestroyed() && (st == null || st.menu == null) && !mIsStartingWindow) {
  invalidatePanelMenu(FEATURE_ACTION_BAR);
  }
  } else {
  mTitleView = (TextView)findViewById(R.id.title);
  if (mTitleView != null) {
  mTitleView.setLayoutDirection(mDecor.getLayoutDirection());
  if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
  View titleContainer = findViewById(
  R.id.title_container);
  if (titleContainer != null) {
  titleContainer.setVisibility(View.GONE);
  } else {
  mTitleView.setVisibility(View.GONE);
  }
  if (mContentParent instanceof FrameLayout) {
  ((FrameLayout)mContentParent).setForeground(null);
  }
  } else {
  mTitleView.setText(mTitle);
  }
  }
  }

  if (mDecor.getBackground() == null && mBackgroundFallbackResource != 0) {
  mDecor.setBackgroundFallback(mBackgroundFallbackResource);
  }

  // Only inflate or create a new TransitionManager if the caller hasn't
  // already set a custom one.
  if (hasFeature(FEATURE_ACTIVITY_TRANSITIONS)) {
  if (mTransitionManager == null) {
  final int transitionRes = getWindowStyle().getResourceId(
  R.styleable.Window_windowContentTransitionManager,
  0);
  if (transitionRes != 0) {
  final TransitionInflater inflater = TransitionInflater.from(getContext());
  mTransitionManager = inflater.inflateTransitionManager(transitionRes,
  mContentParent);
  } else {
  mTransitionManager = new TransitionManager();
  }
  }

  mEnterTransition = getTransition(mEnterTransition, null,
  R.styleable.Window_windowEnterTransition);
  mReturnTransition = getTransition(mReturnTransition, USE_DEFAULT_TRANSITION,
  R.styleable.Window_windowReturnTransition);
  mExitTransition = getTransition(mExitTransition, null,
  R.styleable.Window_windowExitTransition);
  mReenterTransition = getTransition(mReenterTransition, USE_DEFAULT_TRANSITION,
  R.styleable.Window_windowReenterTransition);
  mSharedElementEnterTransition = getTransition(mSharedElementEnterTransition, null,
  R.styleable.Window_windowSharedElementEnterTransition);
  mSharedElementReturnTransition = getTransition(mSharedElementReturnTransition,
  USE_DEFAULT_TRANSITION,
  R.styleable.Window_windowSharedElementReturnTransition);
  mSharedElementExitTransition = getTransition(mSharedElementExitTransition, null,
  R.styleable.Window_windowSharedElementExitTransition);
  mSharedElementReenterTransition = getTransition(mSharedElementReenterTransition,
  USE_DEFAULT_TRANSITION,
  R.styleable.Window_windowSharedElementReenterTransition);
  if (mAllowEnterTransitionOverlap == null) {
  mAllowEnterTransitionOverlap = getWindowStyle().getBoolean(
  R.styleable.Window_windowAllowEnterTransitionOverlap, true);
  }
  if (mAllowReturnTransitionOverlap == null) {
  mAllowReturnTransitionOverlap = getWindowStyle().getBoolean(
  R.styleable.Window_windowAllowReturnTransitionOverlap, true);
  }
  if (mBackgroundFadeDurationMillis < 0) {
  mBackgroundFadeDurationMillis = getWindowStyle().getInteger(
  R.styleable.Window_windowTransitionBackgroundFadeDuration,
  DEFAULT_BACKGROUND_FADE_DURATION_MS);
  }
  if (mSharedElementsUseOverlay == null) {
  mSharedElementsUseOverlay = getWindowStyle().getBoolean(
  R.styleable.Window_windowSharedElementsUseOverlay, true);
  }
  }
  }
  }

2.2WindowManager、WindowManagerGlobal、ViewRootImpl、WindowManagerService


    
    1WindowManagerImpl是客户端WindowManager管理接口的实现,WindowManagerImpl内部维护一个单例的WindowManagerGlobal对象,WindowManagerImpl通过该对象转发客户端的窗口管理请求。客户端在创建窗口时首先调用getWindowManager获得本地窗口管理对象,并调用其addView、removeView、UpdateViewLayout为窗口进行布局控制
  2)ViewManagerImp是Viewmanager的实现,该类并没有直接实现Window的操作,而是由WindowmanagerGlo
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值