Android知识Android技术知识Android开发

Activity的启动过程第二篇

2016-09-09  本文已影响86人  b496178cdc84

首先,还是先将总体的顺序写出来
1、Laucher组件 首先向AMS(AndroidManagerService)发送一个启动Mainactivity的请求, 这个请求是进程间通信的。
2、AMS首先将要启动的MainActivity组件的信息保留起来,然后向Laucher组件发送一个进入终止状态的进程通信。
3、然后,Laucher组件会接收到AMS发来的中止请求,进入中止状态, 然后再向AMS发送消息,告诉AMS 我已经进入中止状态了,你请继续做你的是事情,这样AMS就能继续进行启动Aty的操作。
4、由于MainAty的启动是在Lauther程序中启动的,Lauther中止了,程序应用进程也就不存在了,然后AMS就会新启动一个应用进程。
5、新的应用进程启动后,就会告诉AMS 我(新的应用进程)已经启动好了,然后发一个通信请求给AMS。
6、接收到新应用进程发来的通信后,AMS就会把第二步保留的组件信息 传递给新的进程,然后新的进程就可以靠这些信息去启动MainAty。

上一篇启动过程分析完了第一步,这一篇来分析第二步。也是先放源码。

    public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            final View decor = mWindow != null ? mWindow.peekDecorView() : null;
            if (decor != null) {
                decor.cancelPendingInputEvents();
            }
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }


我们单独把这段代码拿出来分析

        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }

可以看到,这里面调用了Instrument类,并且执行了execStartActivity()这个方法。
我么先简单了解一下这个Instrument类的作用。
Instrument类的主要作用:他用来监控,应用程序和系统之间的交互操作。
OK,现在可以看一下里面的参数,有一个mMainThread.这个mMainThread是Activity的一个成员变量ActivityThread,系统每打开一个应用,都会初始化一个ActivityThread的实例,并且传给每个应用的父亲Activity(这个父亲Activity就是我们的每一个继承的Activity),然后看一下mMainThread.getApplicationThread()这个,好的 ,看一下ActivityThread的源码里面这个方法。

   public ApplicationThread getApplicationThread()
    {
        return mAppThread;
    }

返回的是一个mAppThread,这个Application其实就是一个IBinder的本地对象。有兴趣的道友可以看一下源码,会调用mAppThread.asBinder方法,可以验证这一点。这个mAppThread对象可以和Launcher通信,在执行了execStartActivity()之后就会通过binder通知Launcher进入停止状态。

在这里,作者罗老师强调了一个地方,就是这个mToken,查看源码知道,这个mToken是个IBinder类型的成员变量,他是一个IBinder的代理对象,指向了,AMS中,一个类型为ActivityRecord的本地对象。每一个启动的Activity组件,在AMS中都有一个对应的ActivityRecord的对象,这个ActivityRecord对象,是用来维护对应的Activity的运行状态以及信息。

到这个地方,第二部就完成了。

OK 继续深入execStartActivity()这个方法。先看源码

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
            //主要过程放在IApplication中执行
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                //这里查找Activity 是否存在
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            //这里是真正打开Activity的地方
            //这个ActivityManagerNative.getDefault()是AMS的代理对象,调用startActivity来将activity启动起来
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
        return null;
    }

我们着重看这段代码

            //这里是真正打开Activity的地方
            //这个ActivityManagerNative.getDefault()是AMS的代理对象,调用startActivity来将activity启动起来
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, null, options);

可以看到,在execStartActivity里面,调用了ActivityManagerNative.getDefault(),那这个ActivityManagerNative.getDefault()返回的是什么呢?看一下源码。

  static public IActivityManager getDefault() {
        return gDefault.get();
    }

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

这个返回的是一个IActivityManager对象,这个IAM 实际上是AMS(AndroidManagerService)的代理对象,然后通过调用它的startActivity来通知AMS将一个Activity组件启动起来。
第二篇先写到这里,一点一点消化。

上一篇 下一篇

猜你喜欢

热点阅读