Android主线程到底是什么(二)

时间:2021-11-23 18:30:29

接着上一篇,现在我们的主线程已经处理了第一个Message,在这个处理中执行了Application的onCreate函数,紧接着就是等待第二个消息了。
那么第二个消息是什么时候发送的呢?

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
          ....
            thread.bindApplication(processName, appInfo, providers, 
                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    mConfiguration, app.compat, getCommonServicesLocked(),
                    mCoreSettingsObserver.getCoreSettingsLocked());

            .....
                    if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
                        didSomething = true;
                    }

         ....
    }

我们回到上一篇的attachApplicationLocked函数,在这个函数中,不仅调用thread.的bindApplication函数(这个函数的作用上一节已经说过了)。还调用了mMainStack.realStartActivityLocked(hr, app, true, true)

 final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
     ....
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
                    System.identityHashCode(r), r.info, mService.mConfiguration,
                    r.compat, r.icicle, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profileFile, profileFd,
                    profileAutoStop);

    ...
}

realStartActivityLocked中再次远程调用ApplicationThread的scheduleLaunchActivity函数

 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                Bundle state, List<ResultInfo> pendingResults,
                List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
            ActivityClientRecord r = new ActivityClientRecord();
            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;
            r.startsNotResumed = notResumed;
            r.isForward = isForward;
            r.profileFile = profileName;
            r.profileFd = profileFd;
            r.autoStopProfiler = autoStopProfiler;
            updatePendingConfiguration(curConfig);

            //和上一篇一样  通过这个函数向MessageQueue中添加一个消息,what值为LAUNCH_ACTIVITY
            queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
        }

看到了吗,就是通过 queueOrSendMessage添加消息的,这个函数上一节已经有过说明。

loop()中取出该消息,分发到mH中处理该消息

public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null);
                } break;
              ......
            }
         }

 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
      ....
        Activity a = performLaunchActivity(r, customIntent);
   ....
}
 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
       .....
        Activity activity = null;
        try {

//获取类加载器,创建activity对象
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
          ....
        } catch (Exception e) {
           ....
        }
        try {
        //获取当前Application对象,因为前面已经创建过了,所以这里直接返回
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ...
            if (activity != null) {
                ContextImpl appContext = new ContextImpl();
                appContext.init(r.packageInfo, r.token, this);
                appContext.setOuterContext(activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
             ...
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config);
               ...
                activity.mCalled = false;
                mInstrumentation.callActivityOnCreate(activity, r.state);
              ...
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                ...
                }
            }
            r.paused = true;
            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;
}    

performLaunchActivity函数中主要做了这么几件事
1.创建Activity对象。2.初始化activity对象的上下文
3.为当前activity创建窗口。 4.分别调用activity的onCreate onResume等函数,完成应用程序希望在特定时刻完成的操作。

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) {
        attachBaseContext(context);
        mFragments.attachActivity(this);

        mWindow = PolicyManager.makeNewWindow(this);
        mWindow.setCallback(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();

      ....
    }

PolicyManager.makeNewWindow(this);
创建显示的窗口对象, mWindow.setCallback(this);
为窗口对象设置回调接口,Activity实现了该接口。

回到performLaunchActivity函数中,mInstrumentation.callActivityOnCreate(activity, r.state);

  public void callActivityOnCreate(Activity activity, Bundle icicle) {
       ....      
        activity.performCreate(icicle);

       ....
    }

 final void performCreate(Bundle icicle) {
        onCreate(icicle);
        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                com.android.internal.R.styleable.Window_windowNoDisplay, false);
        mFragments.dispatchActivityCreated();
    }

callActivityOnCreate中通过Activity的performCreate函数调用了Activity的onCreate和fragment的onCreate。

 if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }

首次打开activity, r.activity.mFinished==false,所有执行activity.performStart();内部调用了activity的onStart()和fragment的onStart函数。

mInstrumentation.callActivityOnPostCreate(activity, r.state);
调用Activity的onPostCreate()函数

回到 handleLaunchActivity函数中, handleResumeActivity(r.token, false, r.isForward);它内部调用Activity的onResume函数,并绘制了界面。