Activity启动过程详解

      本文分析Activity的流程图如下,下图是整个Activity启动的方法调用链,主要涉及到的类包括:Activity、Instrumentation、ActivityManagerService、ActivityStackSuper、ActivityStack、ActivityThread、ActivityThread.ApplicationThread,至于其他的ProcessRecord、ActivityRecord、TaskRecord等等等等都忽略不计,首先上一张Activity启动过程的方法调用链:

Activity启动过程详解_第1张图片

    

        好,接下来我们开始对源码进行一次分析。

      我们已知要想启动一个Activity的时候直接调用startActivity()或ActivityForResult()方法,实际上startActivity()也是调用了startActivityForResult(),因此,我们从startActivity()开始一步一步的分析。

一、startActivity()的执行过程

   首先来看下startActivity()源码:

@Override
    public void startActivity(Intent intent) {
        startActivity(intent, null);
    }

    @Override
    public void startActivity(Intent intent, Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

     public void startActivityForResult(Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }

    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;
            }
        } 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);
            }
        }
    }
     可以看到我们客户端在启动一个Activity时最多会涉及相关的四个方法,就是当我们直接调用startActivity()时,通过层层调用最后调用了startActivityForResult(Intent intent, int requestCode, Bundle options)这个方法,下面我们就重点研究这个方法:

     先挑简单的说,注意if (requestCode >= 0)判断,当我们调用startActivity()时,默认的requestCode就是-1,所以此时mStartActivity=false,也就是告诉系统当那个被启动的Activity被finish()后前一个Activity不需要收到消息,即onActivityResult()里不会收到任何消息,所以当我们调用startActivityForResult()的时候其requestCode一定要保证大于等于0,否则将不会收到预期效果。

      上面简单说了下startActivity()和startActivityForResult()在使用时注意的细节,接下来就说下它到底是怎么启动的。

      我们知道在startActivityForResult()中首先对 if (mParent == null)进行判断,这个mParent是什么东东呢?它实际上也是一个Activity实例,现在假设我们要启动的一个Activity是自app安装以来首次启动,那么此时mParent为null,他就会执行以下代码:

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;
            }
        }
      首先执行的就是Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this,mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);看起来比较复杂,我们把它剥开来分析,首先是要执行mInstrumentation.execStartActivity(....),看名字直译过来就是“执行启动Activity”,那么mInstrumentation参数是哪里来的呢?什么时候被赋值的呢?我们先不急,先看下execStartActivity()中一个比较重要的参数就是mMainThread.getApplicationThread(),那么这个mMainThread又是从哪里来的呢?什么时候被赋值的呢?其实我们在Activity源码里可以找到蛛丝马迹,mInstrumentation和mMainThread都是在Activity的attach()方法中被赋值的,mMainThread也就是整个app的主线程(UI线程),这个是本文稍后的重点讲解,而mInstrumentation就是一个Instrumentation实例,Instrumentation按照其源码注释的意思就是:

    

/**
 * Base class for implementing application instrumentation code.  When running
 * with instrumentation turned on, this class will be instantiated for you
 * before any of the application code, allowing you to monitor all of the
 * interaction the system has with the application.  An Instrumentation
 * implementation is described to the system through an AndroidManifest.xml's
 *  tag.
 */
     其大意就是这是为实现应用“应用仪表”代码的基类(这么翻译好拗口啊。。),当用这个仪表打开时,这个类会在我们应用的所有代码之前被实例化,允许我们监督所有的系统和本应用之间的交互,对于Instrumentaion的实现,我们需要在AndroidMainfest.xml文件里添加描述。-----以上是直接翻译过来的,用我们的话来说,这个类呢就是用来监督别人的,这种手段用在单元测试方面比较多。

      上面说了那么多废话,话说回来我们该看看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) {
        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();
        
        mMainThread = aThread;
        mInstrumentation = instr;
        mToken = token;
        mIdent = ident;
        mApplication = application;
        mIntent = intent;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;

        mWindow.setWindowManager(null, mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }
       对于attach(),就以前的知识范围来讲与其说Activity的onCreate()方法是app的入口,倒不如说attach()是app的入口(当然这里只是突出attach的地位,并不是说attach就是app的入口,如果硬要讨论程序的入口,依次往上推就是Application的onCreate、ActivityThread的main()、Linux的init()了)。其实仔细看attach()方法就是一个赋值的过程,下面我们来具体看下:

       首先是attachBaseContext(context);这个赋值就是一个Activity的上下文赋值,他就是给ContextWrapper的Context对象的mBase变量赋值。然后就是mFragments.attachActivity(this);这个mFragments是一个FragmentManagerImp实例,它执行的结果就是将Fragment和Activity联系起来。接下来就是mWindow的创建,他实际上就是一个PhoneWindow实例,关于此实例详见我的另一篇博文View的绘制过程 ,然后就是一系列的赋值了,这里这出赋值清单如下:

ActivityThread   mMainThread = aThread;           //在这里赋值主线程
     Instrumentation   mInstrumentation = instr;
     IBinder   mToken = token;
     int   mIdent = ident;
     Application   mApplication = application;
     Intent   mIntent = intent;
     ComponentName   mComponent = intent.getComponent();
     ActivityInfo   mActivityInfo = info;
     CharSequence   mTitle = title;
     Activity   mParent = parent;                    //就是在这里赋值mParent
     String   mEmbeddedID = id;
     NonConfigurationInstances   mLastNonConfigurationInstances = lastNonConfigurationInstances;
       好了,那么我们知道了主线程实例以及Application实例、IBinder实现都是在attach()中赋值的,那么attach()方法是在什么时候被调用的呢?答案就是:attach()在ActivityThread中调用。那么问题来了,第一个入口Activity是在什么时候调用的呢?这就涉及到APK的启动过程了,这篇文章详细看APK的启动过程分析 。好了,现在我们回到mInstrumentation.execStartActivity(this,mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);这个方法的调用上来,首先来看看mMainThread.getApplicationThread(),这个是ActivityThread中的方法,用来获取ApplicationThread的,其实getApplicationThread()方法就直接returnmAppThread ,并无其他操作,mApplicationThread也是在ActivityThread中作为全局变量直接创建的final ApplicationThread mAppThread = new ApplicationThread();

      好了,接下来就看看mInstruction.execStartActivity()方法吧,此方法当然是在Instructation()里了,源码如下:

  

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Fragment target,
        Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.setAllowFds(false);
            intent.migrateExtraStreamToClipData();
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mWho : null,
                        requestCode, 0, null, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
        return null;
    }
       可以看到,该方法的第二个参数是IBinder,但是我们在Activity中调用mInstrumentation他的时候传递的是一各ApplicationThread对象,为什么可以从ApplicationThread强转成IBinder呢?因为ApplicationThread是继承ApplicationThreadNative,此类实现了Binder,Binder实现了IBinder接口,就是这么回事!接着看,IBinder实例contextThread(ApplicationThread对象)又被强转成了IApplicationThread对象,为何可以这么任性的转?因为AplicationThreadNative不紧继承了Binder类还实现了IApplicationThread接口,就是这么回事!不懂的可以点击看下Binder详解!好,继续往下看ActivityManagerNative.getDefault()

                .startActivity(...)此方法是启动一个Activity的核心代码,ActivityManagerNative.getDefault()返回的是一个IActivityManager接口实例,它是由ActivityManagerProxy实现的。我们直接去看ActivityManagerProxy的startActivity()吧:

    public int startActivity(IApplicationThread caller, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, String profileFile,
            ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        data.writeString(profileFile);
        if (profileFd != null) {
            data.writeInt(1);
            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }
        此startActivity()方法主要就是通过Binder机制完成了客户端向服务器端的通信,即调用mRemote.transact()方法完成通信,那么 这个ActivityManagerProxy的mRemote实例是在什么时候赋值的呢?这就涉及到android.util包下的一个Singleton类了,上面我们说到在 mInstruction.execStartActivity()方法中ActivityManagerNative.getDefault().startActivity(...)是关键,此处的getDefault()方法虽然只做了一件事,那就是返回一个IActivityManager实例:
    /**
     * Retrieve the system's default/global activity manager.
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }
     虽然上面的代码很简单,但却是很关键的,首先我们看下gDefault是个什么对象以及怎么创建的:
    private static final Singleton gDefault = new Singleton() {
        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;
        }
    };
       也许你会问,gDefault是一个Singleton类实例,此处直接创建的gDefault实例时重写了其create()方法,但是在调用get()方法时是如何获取到IActivityManager实例的呢?我们来看下Singleton类的源码,他是一个抽象类,就两个方法,一个get()一个onCreate():
/**
 * Singleton helper class for lazily initialization.
 *
 * Modeled after frameworks/base/include/utils/Singleton.h
 *
 * @hide
 */
public abstract class Singleton {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}
      看代码就一目了然,原来我们在 调用ActivityManagerNative.getDefault()时,Singleton的get()方法如果检查到其实例为空就会去执行create()方法并返回,此时就会调用到创建gDefault对象时重写的onCreate()方法,此方法就是重中之重了,正如上面的代码所示,他会先 执行 IBinder b = ServiceManager.getService("activity");获取一个IBinder实例,至于ServiceManager如何通过getService()获取IBinder实例这不是我们的重点讨论。然后就调用ActivityThreadNative方法的asInterface()方法:IActivityManager am = asInterface(b);注意此时这个b是一个IBinder实例,接下来我们看下asInterface()做了什么事情:

    

    /**
     * Cast a Binder object into an activity manager interface, generating
     * a proxy if needed.
     */
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ActivityManagerProxy(obj);
    }
       asInterface()方法在必要的情况下会创建一个代理,也就是ActivityManagerProxy,在创建此代理时传递了一个IBinder实例进去,去他的构造方法看会发现, 此obj直接赋值给了mRemote,至此mRemote对象赋值完毕,那么客户端通过 mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);告诉服务端要启动一个Activity,然后就进入AMS进程了,在服务端的AMS进程中经过一系列的调用,最后回到ActivityThread.ApplicationThread的调用流程了。接下来就该ActivityThread闪亮登场了,客户端已经向服务端请求了要启动一个Activity,并且服务端AMS等已经完成一系列的任务栈创建等工作,然后AMS说让ActivityThread来完成真正的Activity启动,然后ActivityThread就开始要准备启动一个Activity了,实际上在执行ApplicationThreadProxy的schedulePauseActivity()方法时,就是在用IPC原理远程调用ApplicationThread的schedulePauseActivity()方法,其实经过ActivityThread的内部类H(就是一个Handler),最后一步步调用到了handleLaunchActivity()方法,我们看下此类源码:

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        if (r.profileFd != null) {
            mProfiler.setProfiler(r.profileFile, r.profileFd);
            mProfiler.startProfiling();
            mProfiler.autoStopProfiler = r.autoStopProfiler;
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);
  //看这里,此处就生产了一个Activity实例
 Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);

            if (!r.activity.mFinished && r.startsNotResumed) {
                // The activity manager actually wants this one to start out
                // paused, because it needs to be visible but isn't in the
                // foreground.  We accomplish this by going through the
                // normal startup (because activities expect to go through
                // onResume() the first time they run, before their window
                // is displayed), and then pausing it.  However, in this case
                // we do -not- need to do the full pause cycle (of freezing
                // and such) because the activity manager assumes it can just
                // retain the current state it has.
                try {
                    r.activity.mCalled = false;
                    mInstrumentation.callActivityOnPause(r.activity);
                    // We need to keep around the original state, in case
                    // we need to be created again.  But we only do this
                    // for pre-Honeycomb apps, which always save their state
                    // when pausing, so we can not have them save their state
                    // when restarting from a paused state.  For HC and later,
                    // we want to (and can) let the state be saved as the normal
                    // part of stopping the activity.
                    if (r.isPreHoneycomb()) {
                        r.state = oldState;
                    }
                    if (!r.activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPause()");
                    }

                } catch (SuperNotCalledException e) {
                    throw e;

                } catch (Exception e) {
                    if (!mInstrumentation.onException(r.activity, e)) {
                        throw new RuntimeException(
                                "Unable to pause activity "
                                + r.intent.getComponent().toShortString()
                                + ": " + e.toString(), e);
                    }
                }
                r.paused = true;
            }
        } else {
            // If there was an error, for any reason, tell the activity
            // manager to stop us.
            try {
                ActivityManagerNative.getDefault()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null);
            } catch (RemoteException ex) {
                // Ignore
            }
        }
    }
        对于上面的方法,我们直接看重点performLaunchActivity()这个方法的调用,因为正是该方法生成了一个Activity实例,接下来我们看下该方法是如何完成Activity的创建的:

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        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);
        }

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            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) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config);

                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;
                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.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);
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            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;
    }
       看起来此方法比较长啊有木有,我们只看关键的,因为我们现在只关心Activity实例的创建!不关心其他的特性!~ ~!所以呢我这里选取一个最重要的一部分拿出来:

  

        Activity activity = null;
        try {
       //注意,这个r.packageInfo是一个LoadedApk实例,
      java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            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);
            }
        }
    可以看到生成Activity实例的代码又糊掉了Instrumentation里去了,我们去看看该类的newActivity():
    /**
     * Perform instantiation of the process's {@link Activity} object.  The
     * default implementation provides the normal system behavior.
     * 
     * @param cl The ClassLoader with which to instantiate the object.
     * @param className The name of the class implementing the Activity
     *                  object.
     * @param intent The Intent object that specified the activity class being
     *               instantiated.
     * 
     * @return The newly instantiated Activity object.
     */
    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }

      从上可以看出来,一个Activity的实例是被反射出来的,而不是new出来的T_T,以后有人问Activity实例时怎么创建的,你就回答是系统反射出来的好了,哈哈~。以上说了那么多,其实最关键的是客户端如何通知服务端来进行Activity启动,这种通信机制后面会另外开一片文章说道。

     以上说了半天Activity的诞生,都是源于Instrumentmentation的execStartActivity()的int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mWho : null,
                        requestCode, 0, null, null, options);的执行,分析完之后发现他还返回了一个参数,这个参数有什么用呢?当然有用了,接下来会调用方法来对Activity启动的结构进行告知用户,如果启动出问题了就报异常,启动成功就成功吧:

    /*package*/ static void checkStartActivityResult(int res, Object intent) {
//如果启动成功直接return掉
 if (res >= ActivityManager.START_SUCCESS) {
            return;
        }
        //开始报一系列异常
        switch (res) {
            case ActivityManager.START_INTENT_NOT_RESOLVED:
            //新手最熟悉这种异常吧。。通常忘记在AndroidMainfest.xml文件中添加Activity描述时会异常
            case ActivityManager.START_CLASS_NOT_FOUND:
                if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + ((Intent)intent).getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case ActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            case ActivityManager.START_NOT_ACTIVITY:
                throw new IllegalArgumentException(
                        "PendingIntent is not an activity");
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
    }

        最后贴出一张关于ApplicationThread的关系图,此图参考http://blog.csdn.net/myarrow/article/details/14223493这位兄弟的博客。我觉得这张图画得和本博客得思路讲解一致,故拿过来贴在此处,本人就懒得去画啦~

     Activity启动过程详解_第2张图片

        好了,关于Activity的启动方式我们已经说完了,下一篇文章就说说Activity启动的四种模式和Activity栈吧!总的来说,在ActivityThread中一个Activity被启动时相关方法调用层次时酱紫的:schedule->handle->perform->activity/Insturmation。

   

你可能感兴趣的:(Android框架层,炭灰似雪)