源码 Activity 的 window 创建过程

ActivityThread # performLaunchActivity()

2533    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2534        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
                                    .......
2572
2573        try {
2574            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2575
2576            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2577            if (localLOGV) Slog.v(
2578                    TAG, r + ": app=" + app
2579                    + ", appName=" + app.getPackageName()
2580                    + ", pkg=" + r.packageInfo.getPackageName()
2581                    + ", comp=" + r.intent.getComponent().toShortString()
2582                    + ", dir=" + r.packageInfo.getAppDir());
2583
2584            if (activity != null) {
2585                Context appContext = createBaseContextForActivity(r, activity);
2586                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2587                Configuration config = new Configuration(mCompatConfiguration);
2588                if (r.overrideConfig != null) {
2589                    config.updateFrom(r.overrideConfig);
2590                }
2591                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2592                        + r.activityInfo.name + " with config " + config);
2593                Window window = null;
2594                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
2595                    window = r.mPendingRemoveWindow;
2596                    r.mPendingRemoveWindow = null;
2597                    r.mPendingRemoveWindowManager = null;
2598                }
2599                activity.attach(appContext, this, getInstrumentation(), r.token,
2600                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
2601                        r.embeddedID, r.lastNonConfigurationInstances, config,
2602                        r.referrer, r.voiceInteractor, window);
2603
2604                if (customIntent != null) {
2605                    activity.mIntent = customIntent;
2606                }
2607                r.lastNonConfigurationInstances = null;
2608                activity.mStartedActivity = false;
2609                int theme = r.activityInfo.getThemeResource();
2610                if (theme != 0) {
2611                    activity.setTheme(theme);
2612                }
2613
2614                activity.mCalled = false;
2615                if (r.isPersistable()) {
2616                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2617                } else {
2618                    mInstrumentation.callActivityOnCreate(activity, r.state);
2619                }
2620                if (!activity.mCalled) {
2621                    throw new SuperNotCalledException(
2622                        "Activity " + r.intent.getComponent().toShortString() +
2623                        " did not call through to super.onCreate()");
2624                }
2625                r.activity = activity;
2626                r.stopped = true;
2627                if (!r.activity.mFinished) {
2628                    activity.performStart();
2629                    r.stopped = false;
2630                }
2631                if (!r.activity.mFinished) {
2632                    if (r.isPersistable()) {
2633                        if (r.state != null || r.persistentState != null) {
2634                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2635                                    r.persistentState);
2636                        }
2637                    } else if (r.state != null) {
2638                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2639                    }
2640                }
2641                if (!r.activity.mFinished) {
2642                    activity.mCalled = false;
2643                    if (r.isPersistable()) {
2644                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
2645                                r.persistentState);
2646                    } else {
2647                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
2648                    }
2649                    if (!activity.mCalled) {
2650                        throw new SuperNotCalledException(
2651                            "Activity " + r.intent.getComponent().toShortString() +
2652                            " did not call through to super.onPostCreate()");
2653                    }
2654                }
2655            }
2656            r.paused = true;
2657
2658            mActivities.put(r.token, r);
2659
2660        } catch (SuperNotCalledException e) {
2661            throw e;
2662
2663        } catch (Exception e) {
2664            if (!mInstrumentation.onException(activity, e)) {
2665                throw new RuntimeException(
2666                    "Unable to start activity " + component
2667                    + ": " + e.toString(), e);
2668            }
2669        }
2670
2671        return activity;
2672    }
ActivityThread 中的 performLaunchActivity 来完成整个启动过程,这个方法内部会通过 
类加载器创建 Activity 的实例对象,并调用其 attach方法为其关联运行过程中所依赖的一系列上下环境变量。
Activity # attach()
final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor,
        Window window) {
    attachBaseContext(context);


    mFragments.attachHost(null /*parent*/);


    mWindow = new PhoneWindow(this, window);
    mWindow.setWindowControllerCallback(this);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
        mWindow.setSoftInputMode(info.softInputMode);
    }
    if (info.uiOptions != 0) {
        mWindow.setUiOptions(info.uiOptions);
    }
    mUiThread = Thread.currentThread();


    mMainThread = aThread;
    mInstrumentation = instr;
    mToken = token;
    mIdent = ident;
    mApplication = application;
    mIntent = intent;
    mReferrer = referrer;
    mComponent = intent.getComponent();
    mActivityInfo = info;
    mTitle = title;
    mParent = parent;
    mEmbeddedID = id;
    mLastNonConfigurationInstances = lastNonConfigurationInstances;
    if (voiceInteractor != null) {
        if (lastNonConfigurationInstances != null) {
            mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
        } else {
            mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                    Looper.myLooper());
        }
    }


    mWindow.setWindowManager(
            (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
            mToken, mComponent.flattenToString(),
            (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) {
        mWindow.setContainer(mParent.getWindow());
    }
    mWindowManager = mWindow.getWindowManager();
    mCurrentConfig = config;
}

PhoneWindow # PhoneWindow()

@Override
public void setContentView(View view) {
    setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}

@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
    // 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();
    } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
        mContentParent.removeAllViews();
    }

    if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
        view.setLayoutParams(params);
        final Scene newScene = new Scene(mContentParent, view);
        transitionTo(newScene);
    } else {
        mContentParent.addView(view, params);
    }
    final Callback cb = getCallback();
    if (cb != null && !isDestroyed()) {
        cb.onContentChanged();
    }
}
经过上面三个步骤,到这里为止 decorView 已经被创建 并初始化完毕,activity 的布局文件已经成功添加到
decorView 的 mContentParent 中,
但是 这时候 decorView 还没有被 windowManager 添加到 window 中。
在 ActivityThread 的 handleResumeActivity 方法中,首先会调用 activity 的onResume 方法,
接着 会调用 Activity 的 makeVisible ,

final void handleResumeActivity(IBinder token,
                                boolean clearHide, boolean isForward, boolean reallyResume) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    // TODO Push resumeArgs into the activity for consideration
    ActivityClientRecord r = performResumeActivity(token, clearHide);

    if (r != null) {
        final Activity a = r.activity;

        if (localLOGV) Slog.v(
                TAG, "Resume " + r + " started activity: " +
                        a.mStartedActivity + ", hideForNow: " + r.hideForNow
                        + ", finished: " + a.mFinished);

        final int forwardBit = isForward ?
                WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;

        // If the window hasn't yet been added to the window manager,
        // and this guy didn't finish itself or start another activity,
        // then go ahead and add the window.
        boolean willBeVisible = !a.mStartedActivity;
        if (!willBeVisible) {
            try {
                willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
                        a.getActivityToken());
            } catch (RemoteException e) {
            }
        }
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (a.mVisibleFromClient) {
                a.mWindowAdded = true;
                wm.addView(decor, l);
            }

            // If the window has already been added, but during resume
            // we started another activity, then don't yet make the
            // window visible.
        } else if (!willBeVisible) {
            if (localLOGV) Slog.v(
                    TAG, "Launch " + r + " mStartedActivity set");
            r.hideForNow = true;
        }

        // Get rid of anything left hanging around.
        cleanUpPendingRemoveWindows(r);

        // The window is now visible if it has been added, we are not
        // simply finishing, and we are not starting another activity.
        if (!r.activity.mFinished && willBeVisible
                && r.activity.mDecor != null && !r.hideForNow) {
            if (r.newConfig != null) {
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                        + r.activityInfo.name + " with newConfig " + r.newConfig);
                performConfigurationChanged(r.activity, r.newConfig);
                freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
                r.newConfig = null;
            }
            if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
                    + isForward);
            WindowManager.LayoutParams l = r.window.getAttributes();
            if ((l.softInputMode
                    & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                    != forwardBit) {
                l.softInputMode = (l.softInputMode
                        & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                        | forwardBit;
                if (r.activity.mVisibleFromClient) {
                    ViewManager wm = a.getWindowManager();
                    View decor = r.window.getDecorView();
                    wm.updateViewLayout(decor, l);
                }
            }
            r.activity.mVisibleFromServer = true;
            mNumVisibleActivities++;
            if (r.activity.mVisibleFromClient) {
                r.activity.makeVisible();
            }
        }

        if (!r.onlyLocalRequest) {
            r.nextIdle = mNewActivities;
            mNewActivities = r;
            if (localLOGV) Slog.v(
                    TAG, "Scheduling idle handler for " + r);
            Looper.myQueue().addIdleHandler(new Idler());
        }
        r.onlyLocalRequest = false;

        // Tell the activity manager we have resumed.
        if (reallyResume) {
            try {
                ActivityManagerNative.getDefault().activityResumed(token);
            } catch (RemoteException ex) {
            }
        }

    } else {
        // If an exception was thrown when trying to resume, then
        // just end this activity.
        try {
            ActivityManagerNative.getDefault()
                    .finishActivity(token, Activity.RESULT_CANCELED, null, false);
        } catch (RemoteException ex) {
        }
    }
}
activity # makeVisible()

void makeVisible() {
    if (!mWindowAdded) {
        ViewManager wm = getWindowManager();
        wm.addView(mDecor, getWindow().getAttributes());
        mWindowAdded = true;
    }
    mDecor.setVisibility(View.VISIBLE);
}
myBase笔记:  https://github.com/ycyangchun/androidNode

Android API :http://www.android-doc.com/reference/packages.html 
http://tool.oschina.net/uploads/apidocs/android/reference/packages.html 
Android 源码:http://androidxref.com/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值