码迷,mamicode.com
首页 > 其他好文 > 详细

四大组件的工作过程探索(一)

时间:2016-04-29 15:19:48      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:

四大组件的运行状态:


Android中的四大组件中除了BroadcastReceiver以外,其他三种组件都必须在Android Mainfrst中注册。对于,BroadcastReceiver来说,他既可以在AndroidMainfrst中注册也可以通过代码来注册。在调用方式上,Activity,Service和BroadcastReceiver需要借助Intent,而ContentProvider则无需借助Intent。

Activity的工作过程:

为了方便日常的开发工作,系统对四大组件的工作过程进行了很大程度的封装,这使得开发者无需关注实现细节即可快速的使用四大组件。Activity作为很重要的一个组件,其内部工作过程系统当然也是做了很多的封装,这种封装使得启动一个Activity变得异常的简单。在显示调用的情形下,只需要通过如下代码即可完成:
Intent intent=new Intent(this,TestActivity.class);
startActivity(intent);

通过上面的代码即可启动一个具体的activity,然后新Activity就会被系统启动并展示在 用户的眼前,这个过程对于Android开发者来说最普通不过了,这也是很理所当然的事情,但是有没有想过系统内部到底是如何启动一个Activity的呢?下面我们就来介绍一下。

注意一点:在研究内部实现上应该更加侧重于对整体流程的把握,而不能深入代码细节不能自拔,太深入代码细节往往会导致越看越迷茫的撞到。无法对整体流程建立足够的认识,取而代之的是繁琐的细节。但是代码的细节本身不具有太多的指导意义,因此这种学习状态是要极力避免的。所以本博客会侧重于对Activity工作过程的分析整体流程。

我们从Acitivity的startActivity的方法开始分析,startActivity的方法有好几种重载方式,但是他们最终都会调用startActivityForResult方法,实现如下:

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

在上面的代码中,我们只需要关注mParent==null这部分逻辑,mParent代表的是ActivityGroup,ActivityGroup最开始被用来在一个界面中嵌入多个子Activity,但是其在API13中已经被废弃了,系统推荐采用Fragment来代替ActivityGroup,Fragment的好处就不多说了、在上面的代码中需要注意mMainThread.getApplicationThread()这个参数,他的类型是ApplicationThread,ApplicationThread是ActivityThread在Activity的启动过程中发挥着很重要的作用。接着看一下Instrumentation的execStartActiivty方法。如下所示:

 public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity 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<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();
            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;
    }


从上面的代码来看,启动Actiivty真正的实现由ActivityManagerNative.getDefault()的startActivity方法完成。ActivityManagerService(简称AMS)继承自Binder并实现了IActivityManager这个Binder接口,因此AMS也是一个Binder,他是IActivityManager的具体实现。由于ActivityManagerNative.getDefault()其实是一个IActivityManager类型的Binder对象,因此他的具体实现是AMS。可以发现,在ActivityManagerNative中。AMS这个Binder对象采用单例模式对外提供,Singleton是一个单利的封装类,第一次调用它的get方法时他会通过create方法来初始化AMS这个Binder对象,在后续的调用中则直接返回之前创建的对象,源码如下:

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

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager More ...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;
        }
    };

再附上ActivityManagerNative的完整源码地址:源码,有兴趣的可以去阅读一下。
从上面的分析可以知道,Activity由ActivityManagerNative.getDefault()来启动。而ActivityManagerNative.getDefault()实际上是AMS,因此Activity的启动过程又转移到了AMS中,为了继续分析这个过程,只需要查看AMS的startActivity方法即可,在分析AMS的startActivity方法之前,我们先回过头来看一下Instrumentation的execStartActivity方法,其中有一行代码:checkStartActivityResult(result,intent),直观上看起来这个方法的作用像是在检查启动Activity的记过,他的具体实现如下所示:

/*package*/ static void checkStartActivityResult(int res, Object intent) {
        if (res >= ActivityManager.START_SUCCESS) {
            return;
        }
        
        switch (res) {
            case ActivityManager.START_INTENT_NOT_RESOLVED:
            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);
        }
    }
从上面的代码可以看出,checkStartActivityResult的作用很明显,就是检查启动Activity的结果,当无法正确启动一个Activity时,这个方法会抛出异常信息,其中最熟悉不过的就是"unable to find expliit activity class; have you declared this activity in your androidmainfest.xml"这个异常我就不说了,你懂的。

接着我们继续分析AMS的startActivity方法,如下所示:

public final int More ...startActivity(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags,
             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                 resultWho, requestCode,
                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
     }
public final int More ...startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags,
             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
         enforceNotIsolatedCaller("startActivity");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivity", null);
         return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
                 null, null, options, userId);
     }

可以看出,Activity的启动过程又转移到了ActivityStackSupervisor的startActivityMayWait方法中了。在startActivityMayWait中又调用了startActivityLocked方法,接着startActivityLocked又调用了ActivityStack的resumeTopActivityiesLocked方法,这个时候启动过程已经从ActivityStackSupervisor转移到了ActivityStack。

ActivityStack的resumeTopActivitiesLocked方法的实现如下所示:
final boolean More ...resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            inResumeTopActivity = false;
        }
        return result;
    }

从上面的代码可以看出,resumeTopActivityLocked调用了resumeTopActivityInnerLocked方法,resumeTopActivityInnerLocked方法又调用了ActivityStackSupervisor的satrtSpecificActivityLocked方法,satrtSpecificActivityLocked的源码如下:

void More ...startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

从上面的代码可以看出,satrtSpecificActivityLocked方法调用了realStartActivityLocked方法,为了更清晰的说明Activity的启动过程在ActivityStatckSupervisor和ActivityStack之间的传递顺序,下面给出一张流程图。


技术分享


在ActivityStackSupervisor的realStartActivityLocked方法中 又如下 一段代码:

 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
                    results, newIntents, !andResume, mService.isNextTransitionForward(),
                    profilerInfo);

这段代码很重要,其中app.thread的类型为IApplicationThread,IApplicationThread的声明如下:

因为他继承了IInterface接口,所以他是一个Binder类型的接口,从IApplicationThread声明的接口方法中可以看出,其内部包含了大量启动,停止Activity 的接口,此外还包含了启动和停止服务的接口,从接口的方法的命名可以猜测,IApplicationThread这个Binder接口的实现者完成了大量和Activity以及Service启动停止相关的功能。

那么IApplicationThread的实现者到底是什么?答案就是ActivityThread中的内部类ApplicationThread,洗面来看ApplicationThread的定义:

 private class More ...ApplicationThread extends ApplicationThreadNative

public abstract class More ...ApplicationThreadNative extends Binder
          implements IApplicationThread 
可以看出,ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative则继承了Binder并实现了IApplicationThread接口。如果读者还记得系统的AIDL文件自动生成的代码,就会发现ApplicationThreadNative的作用其实和系统为AIDL文件生成的类是一样的。

在ApplicationThreadNative的内部,还有一个ApplicationThreadProxy类,这个类的实现如下所示,其实这个内部类也是系统为AIDL文件自动生成的代理类。所以ApplicationThreadNative就是IApplicationThread的实现者,由于ApplicationThreadNative被系统定义为抽象类,所以ApplicationThread就成了IApplicationThread的最终实现者了。

class More ...ApplicationThreadProxy implements IApplicationThread {
     private final IBinder mRemote;
     
     public More ...ApplicationThreadProxy(IBinder remote) {
         mRemote = remote;
     }
     
     public final IBinder More ...asBinder() {
         return mRemote;
     }
     
     public final void More ...schedulePauseActivity(IBinder token, boolean finished,
             boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         data.writeInt(finished ? 1 : 0);
         data.writeInt(userLeaving ? 1 :0);
         data.writeInt(configChanges);
         data.writeInt(dontReport ? 1 : 0);
         mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
 
     public final void More ...scheduleStopActivity(IBinder token, boolean showWindow,
             int configChanges) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         data.writeInt(showWindow ? 1 : 0);
         data.writeInt(configChanges);
         mRemote.transact(SCHEDULE_STOP_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
...
}
绕了一大圈,Activity的启动过程最终回到了ApplicationThread中,ApplicationThread通过scheduleLaunchActivity方法来启动Activity,代码如下:

public final void More ...scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                 IVoiceInteractor voiceInteractor, int procState, Bundle state,
                 PersistableBundle persistentState, List<ResultInfo> pendingResults,
                 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                 ProfilerInfo profilerInfo) {
 
             updateProcessState(procState, false);
 
             ActivityClientRecord r = new ActivityClientRecord();
 
             r.token = token;
             r.ident = ident;
             r.intent = intent;
             r.voiceInteractor = voiceInteractor;
             r.activityInfo = info;
             r.compatInfo = compatInfo;
             r.state = state;
             r.persistentState = persistentState;
 
             r.pendingResults = pendingResults;
             r.pendingIntents = pendingNewIntents;
 
             r.startsNotResumed = notResumed;
             r.isForward = isForward;
 
             r.profilerInfo = profilerInfo;
 
             updatePendingConfiguration(curConfig);
 
             sendMessage(H.LAUNCH_ACTIVITY, r);
        }

接下来看一下Handler H对消息的处理,如下所示:

private class More ...H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;
        public static final int PAUSE_ACTIVITY          = 101;
        public static final int PAUSE_ACTIVITY_FINISHING= 102;
        public static final int STOP_ACTIVITY_SHOW      = 103;
        public static final int STOP_ACTIVITY_HIDE      = 104;
        public static final int SHOW_WINDOW             = 105;
        public static final int HIDE_WINDOW             = 106;
       public static final int RESUME_ACTIVITY         = 107;
public void More ...handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case RELAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                    handleRelaunchActivity(r);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case PAUSE_ACTIVITY:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                    handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
                            (msg.arg1&2) != 0);
                    maybeSnapshot();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                   break;
....
}
<span style="font-family: monospace;font-size:14px; white-space: pre;"> </span><span class="kw" style="color: rgb(127, 0, 85); font-weight: bold; font-family: monospace;font-size:14px; white-space: pre;">if</span><span style="font-family: monospace;font-size:14px; white-space: pre;"> (</span><span class="mark-5#1" style="font-family: monospace;font-size:14px; white-space: pre;"><a target=_blank href="http://grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/5.0.0_r2-robolectric-0/android/app/ActivityThread.java#ActivityThread.0DEBUG_MESSAGES" title="boolean DEBUG_MESSAGES" class="hidden" style="padding: 0px; margin: 0px; color: rgb(0, 0, 0); text-decoration: none;">DEBUG_MESSAGES</a></span><span style="font-family: monospace;font-size:14px; white-space: pre;">) Slog.</span><a target=_blank href="http://grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/5.0.0_r2-robolectric-0/android/util/Slog.java#Slog.v%28java.lang.String%2Cjava.lang.String%29" title="android.util.Slog.v(java.lang.String,java.lang.String) : int" style="padding: 0px; margin: 0px; color: rgb(51, 102, 187); font-family: monospace;font-size:14px; white-space: pre;">v</a><span style="font-family: monospace;font-size:14px; white-space: pre;">(</span><span class="mark-1#1" style="font-family: monospace;font-size:14px; white-space: pre;"><a target=_blank href="http://grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/5.0.0_r2-robolectric-0/android/app/ActivityThread.java#ActivityThread.0TAG" title="String TAG" class="hidden" style="padding: 0px; margin: 0px; color: rgb(0, 0, 0); text-decoration: none;">TAG</a></span><span style="font-family: monospace;font-size:14px; white-space: pre;">, </span><span class="strliteral" style="color: rgb(42, 0, 255); font-family: monospace;font-size:14px; white-space: pre;">"<<< done: "</span><span style="font-family: monospace;font-size:14px; white-space: pre;"> + </span><a target=_blank href="http://grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/5.0.0_r2-robolectric-0/android/app/ActivityThread.java#ActivityThread.H.codeToString%28int%29" title="android.app.ActivityThread.H.codeToString(int) : String" style="padding: 0px; margin: 0px; color: rgb(51, 102, 187); font-family: monospace;font-size:14px; white-space: pre;">codeToString</a><span style="font-family: monospace;font-size:14px; white-space: pre;">(</span><span class="mark-479#1" style="font-family: monospace;font-size:14px; white-space: pre;">msg</span><span style="font-family: monospace;font-size:14px; white-space: pre;">.</span><span class="mark-480#1" style="font-family: monospace;font-size:14px; white-space: pre;">what</span><span style="font-family: monospace;font-size:14px; white-space: pre;">));</span>
<span style="font-family: monospace;font-size:14px; white-space: pre;">}</span>

从Handler H对“LAUNCH_ACTIVITY”这个消息的处理可以知道,Activity的启动过程 由ActivityThread的handleLaunchActivity方法实现,他的源码如下:

private void handleLaunceActivity(ActivityClientRecord r,Iintent customIntent){
...
if(localLOGV)Slog.v(TAG,"Handling launch of"+r);

Activity a=performLaunchActivity(r,customIntent);

if(a!=null){
r.createdConfig=new Configuration(mConfiguration);
Bundle oldState=r.statr;
handleResumeActivity(r.token,false,r.isForward,!r.activity.mFinished&&!r. startsNotResumed);
...
}
...
}
从上面的源码可以看出,perforLaunchActivity方法最终完成了Activity对象的创建和启动过程,并且ActivityThread通过handleResumeActivity方法来调用被启动Activity的onResume这以生命周期方法。

perforLaunchActivity这个方法主要完成了如下几件事情:

1.从ActivityClientRecord中获取待启动的Activity的组件信息。


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

2.通过Instrumentation的newActivity方法使用类加载器创建Activity对象:

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

至于Instrumentation的newActivity,他的实现比较简单,就是通过类加载器来创建Activity对象:

public Activity More ...newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }

3,通过LoadedApk的makeApplication方法来尝试创建Application对象:


public Application More ...makeApplication(boolean forceDefaultAppClass,
             Instrumentation instrumentation) {
         if (mApplication != null) {
             return mApplication;
         }
 
         Application app = null;
 
         String appClass = mApplicationInfo.className;
         if (forceDefaultAppClass || (appClass == null)) {
             appClass = "android.app.Application";
         }
 
         try {
             java.lang.ClassLoader cl = getClassLoader();
             if (!mPackageName.equals("android")) {
                 initializeJavaContextClassLoader();
             }
             ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
             app = mActivityThread.mInstrumentation.newApplication(
                     cl, appClass, appContext);
             appContext.setOuterContext(app);
         } catch (Exception e) {
             if (!mActivityThread.mInstrumentation.onException(app, e)) {
                 throw new RuntimeException(
                     "Unable to instantiate application " + appClass
                     + ": " + e.toString(), e);
             }
         }
         mActivityThread.mAllApplications.add(app);
         mApplication = app;
 
         if (instrumentation != null) {
             try {
                 instrumentation.callApplicationOnCreate(app);
             } catch (Exception e) {
                 if (!instrumentation.onException(app, e)) {
                     throw new RuntimeException(
                         "Unable to create application " + app.getClass().getName()
                         + ": " + e.toString(), e);
                 }
             }
         }

从makeApplication的实现可以看出,如果Application已经被创建过了,那么就不会再重复创建了,这也意味着一个应用只有一个Application对象,Application对象的创建也是通过Instrumentation来完成,这个过程和Activity的创建一样,都是通过类加载器来实现的,Application创建完毕后,系统会通过Instrumentation的callApplicationOnCreate来调用Application的onCreate方法。

4.创建ContextImpl对象并通过Activity的attach方法来完成一些重要的数据初始化:



ContextImpl是一个很重要的数据结构,他是Context的具体实现,Context中的大部分逻辑都是由ContextImpl来完成的。ContxetImpl是通过Activity的attach的方法和Activity建立关联的,除此之外,在attach方法中Activity还会完成Window的创建并建立自己和Window的关联,这样当Window接受到外部输入事件后,就可以将事件传递给Acivity

5.调用Activity的onCreate方法


mInstrumentation。callActivityOnCreate(activity,r.state),由于Activity的onCreate已经被调用,这也意味着Activity已经完成了整个启动过程。




四大组件的工作过程探索(一)

标签:

原文地址:http://blog.csdn.net/zhuxiaoxuand/article/details/51264944

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!