美文网首页
一张图了解从桌面启动进程

一张图了解从桌面启动进程

作者: me_biubiu | 来源:发表于2020-05-21 14:42 被阅读0次
image

Launcher的startActivity

桌面是Launcher进程的页面,从桌面点击图标启动app,实际是在Launcher启动另一个进程的Activity。首先我们在Launcher的main线程(即所谓UI线程)里调用startActivity,这个方法最终通过Instrumentation调用ActivityManagerProxy的startActivity方法,通过ActivityManagerProxy远程调用ActivityManagerService同名方法。而后System进程会在告知Launcher进程pauseActivity,所以不要在onpause方法中做耗时操作哦!

System的Process.main

如果被启动activity所依附的进程还没有启动,就会初始化该进程。实际的实现是zygote进程与system_server之间通过socket通信,要创建进程时,system_server 进程里通过往socket写入消息,zygote接收到消息后fork出一个进程,最终会调用ActivityThread的main函数。

应用进程的ActivityThread.main


public static void main(String[] args) {

    Looper.prepareMainLooper();

    ActivityThread thread =new ActivityThread();

    thread.attach(false);

    Looper.loop();

}

创建ActivityThread实例,生命Looper开始loop,并调用attach,还会创建 ApplicationThread 对象作为匿名Binder服务端用以跟system_server进程通信,在thread.attach(false) 中通过AMP把 这个对象注册到AMS。

应用进程的bindApplication

通过Binder机制远端调用bindApplication方法实际调用到ActivityThread的handleBindApplication方法。

  // Allow disk access during application and provider setup. This could
        // block processing ordered broadcasts, but later processing would
        // probably end up doing the same disk access.
        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
        try {
            // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
          //实例化Application
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;

            // don't bring up providers in restricted mode; they may depend on the
            // app's custom Application class
            if (!data.restrictedBackupMode) {
                if (!ArrayUtils.isEmpty(data.providers)) {
                    //初始化ContentProvider
                    installContentProviders(app, data.providers);
                    // For process that contains content providers, we want to
                    // ensure that the JIT is enabled "at some point".
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                }
            }

            // Do this after providers, since instrumentation tests generally start their
            // test thread at this point, and we don't want that racing.
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {
                throw new RuntimeException(
                    "Exception thrown in onCreate() of "
                    + data.instrumentationName + ": " + e.toString(), e);
            }

            try {
              //调用Application.onCreate
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
        } finally {
            StrictMode.setThreadPolicy(savedPolicy);
        }

在其中完成了Application的实例化,ContentProvider的实例化Application的onCreate生命周期。

应用进程的performLaunchActivity方法

AMS里面 远程调用ActivityThread的bindApplication同时调用了其scheduleLaunchActivity方法实际调用到performLaunchActivity

  Activity activity = null;
        try {
          //反射实例化Activity
            java.lang.ClassLoader cl = r.packageInfo.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 (activity != null) {
              //ContextImpl实例
                Context appContext = createBaseContextForActivity(r, activity);
                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;
                }
                //Activity的很多功能会委托给ContextImpl实例实现
                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);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                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);
                }
              ... ...
                //Activity.onStart
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
              ///Activity.onRestoreInstanceState
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }

在这个方法中Instrumentation反射创建Activity
调用activity的attach,oncreate,onstart方法。

相关文章

网友评论

      本文标题:一张图了解从桌面启动进程

      本文链接:https://www.haomeiwen.com/subject/rswzohtx.html