WMS窗口大小计算(一)

本文详细解析了Android中Activity从创建到显示的过程,涉及Activity回调onCreate、setContentView,以及WindowManager如何将DecorView添加到Window并显示。重点分析了ViewRootImpl的setView方法、requestLayout和VSync信号的处理流程,阐述了Choreographer在协调动画、输入和绘制中的作用。
摘要由CSDN通过智能技术生成

  本文以打开一个Activity后,到Activity显示后,如何确认各个窗口的大小和位置。不涉及到窗口中的每个view的布局的情况。一个Activity包含了一个PhoneWindow(window),一个Window代表一个窗口。

     Activity并不负责视图控制,只是控制其生命周期和处理事件,真正控制视图的是Window。但Window的添加和显示又与生命周期息息相关。

      在android系统中,一个window界面上出来Activity显示的界面外,至少还可能有如下的元素:状态栏,导航栏和输入法窗口

1 Activity回调onCreate前

     Activity与Window第一次取得联系是ActivityThread的perfomLaunchActivity()调用Activity的attach()方法时,如下图:

在attach方法里,创建一个PhoneWindow对象,然后赋值给成员变量mWindow。因PhoneWindow继承自Window,接下来通过调用Window的setWindowManager,使得Window与WindowManager获得关联。

ActvityThread.performLaunchActivity

  /**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }
​
        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }
​
        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }
​
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }
​
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
​
            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());
​
            if (activity != null) {
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                appContext.setOuterContext(activity);
                //调用Activity.attach方法来建立activity -window -windowmanager的联系
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
​
                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }
​
                activity.mCalled = false;
                //设置activity的状态:onCreate
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
            }
            r.setState(ON_CREATE);
​
            mActivities.put(r.token, r);
​
        } catch (SuperNotCalledException e) {
            throw e;
​
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }
​
        return activity;
    }
    

Activity.attach

 @UnsupportedAppUsage
7703      final void attach(Context context, ActivityThread aThread,
7704              Instrumentation instr, IBinder token, int ident,
7705              Application application, Intent intent, ActivityInfo info,
7706              CharSequence title, Activity parent, String id,
7707              NonConfigurationInstances lastNonConfigurationInstances,
7708              Configuration config, String referrer, IVoiceInteractor voiceInteractor,
7709              Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
7710          attachBaseContext(context);
7711  
7712          mFragments.attachHost(null /*parent*/);
7713  
7714          mWindow = new PhoneWindow(this, window, activityConfigCallback);//创建phoneWindow对象
7715          mWindow.setWindowControllerCallback(this);
7716          mWindow.setCallback(this);
7717          mWindow.setOnWindowDismissedCallback(this);
7718          mWindow.getLayoutInflater().setPrivateFactory(this);
7719          if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
7720              mWindow.setSoftInputMode(info.softInputMode);
7721          }
7722          if (info.uiOptions != 0) {
7723              mWindow.setUiOptions(info.uiOptions);
7724          }
             //UI线程
7725          mUiThread = Thread.currentThread();
              //建立window与WindowManager的关系
7750          mWindow.setWindowManager(
7751                  (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
7752                  mToken, mComponent.flattenToString(),
7753                  (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
7754          if (mParent != null) {
7755              mWindow.setContainer(mParent.getWindow());
7756          }
7757          mWindowManager = mWindow.getWindowManager();
7758          mCurrentConfig = config;
7759  
7760          mWindow.setColorMode(info.colorMode);
7761  
7762          setAutofillOptions(application.getAutofillOptions());
7763          setContentCaptureOptions(application.getContentCaptureOptions());
7764      }

Window.setWindowManger:

frameworks/base/core/java/android/view/Window.java 
770      public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
771              boolean hardwareAccelerated) {
772          mAppToken = appToken;
773          mAppName = appName;
774          mHardwareAccelerated = hardwareAccelerated;
775          if (wm == null) {
776              wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
777          }
778          mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
779      }
​

WindowManager是个接口类,它的实现是在WindowManagerImpl。WindowManagerImpl的重要方法里实质的工作又是交由WindowManagerGlobal处理。两者属于代理者模式。WindowManagerGlobal用于创建、管理、删除ViewRoot。三者关系如下:

 

2 Activity onCreate中调用setContentView

ActivityThread的perfomLaunchActivity在attach完成后,会调用Activity的onCreate方法。应用程序会在onCreate回调中调用setContentView为活动窗口添加布局。

 

Activity.setContentView


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值