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

四大组件的运行状态:

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已经完成了整个启动过程。

时间: 2024-10-20 13:01:10

四大组件的工作过程探索(一)的相关文章

从源码的角度理解四大组件的工作过程——Android开发艺术探索笔记

原文链接http://sparkyuan.me/2016/03/14/四大组件的工作过程/ 转载注明出处 系统对四大组件的过程进行了很大程度的封装,日常开发中并不需要了解底层的工作原理,那么研究这些原理的意义在哪里呢? 如果你想在技术上更进一步,那么了解一些系统的工作原理是十分必要的,也是开发人员日后成长为高级工程师所必备的技术能力. Android作为一个优秀的基于Linux操作系统,其内部一定有很多值得我们学习的地方,通过对Android操作系统的学习对提高开发人员的内功有很大的好处. 如果

第九章:四大组件的工作过程

9.1 四大组件的运行状态 Android的四大组件中除了BroadcastReceiver意外,其他三种组件都必须在AndroidManifest中注册. 在调用方式上,Activity,Service和BroadcastReceiver需要借助Intent,而ContentProvider则无须借助Intent. Activity是一种展示型组件,用于向用户直接地展示一个界面,并且可以接收用户的输入信息从而进行交互. Service是一种计算型组件,用于在后台执行一系列计算任务,需要灵活采用

Android深入四大组件(四)广播的注册、发送和接收过程

相关文章 Android深入理解四大组件系列 前言 我们接着来学习Android四大组件中的BroadcastReceiver,广播主要就是分为注册.接收和发送过程.建议阅读此文前请先阅读Android深入理解四大组件系列的文章,知识重复的部分,本文不再赘述. 1.广播的注册过程 BroadcastReceiver的注册分为两种,分别是静态注册和动态注册,静态注册在应用安装时由PackageManagerService来完成注册过程,关于这一过程,我会在后续的介绍PackageManagerSe

Android深入四大组件(三)Service的绑定过程

相关文章 Android深入理解四大组件系列 前言 我们可以通过调用Context的startService来启动Service,也可以通过Context的bindService来绑定Service,建议阅读此篇文章前请阅读Android深入四大组件(二)Service的启动过程这篇文章,知识点重叠的部分,本篇文章将不再赘述. 1.ContextImpl到ActivityManageService的调用过程 我们可以用bindService方法来绑定Service,它的实现在ContextWra

Android深入四大组件(二)Service的启动过程

相关文章 Android深入理解四大组件系列 前言 此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程.建议阅读此篇文章前,请先阅读Android深入四大组件(一)应用程序启动过程(前篇)和Android深入四大组件(一)应用程序启动过程(后篇)这两篇文章. 1.ContextImpl到ActivityManageService的调用过程 要启动Service,我们会调用startService方法,它的实现在C

Android深入四大组件(五)Content Provider的启动过程

"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> Android深入四大组件(五)Content Provider的启动过程 - 刘望舒的专栏 - 博客频道 - CSDN.NET 刘望舒的专栏 欲为大树,莫与草争 目录视图 摘要视图 订阅 [活动]2017 CSDN博客专栏评选 &nbsp [5月书讯]流畅的Pyth

Android 四大组件 详解

[置顶] Android四大组件详解 分类: Android四大组件2013-02-09 16:23 19411人阅读 评论(13) 收藏 举报 Android开发 注:本文主要来自网易的一个博主的文章,经过阅读,总结,故留下文章在此 Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity : 应用程序中,一个

一个帖子学会Android开发四大组件

这个文章主要是讲Android开发的四大组件,本文主要分为 一.Activity详解 二.Service详解 三.Broadcast Receiver详解 四.Content Provider详解 外加一个重要组件 intent的详解. 文章有部分内容来自网络,本文是一个总结性文章. 一.Activity详解 Activty的生命周期的也就是它所在进程的生命周期. 一个Activity的启动顺序: onCreate()-->onStart()-->onResume() 当另一个Activity

android四大组件--ContentProvider详解

一.相关ContentProvider概念解析: 1.ContentProvider简介 在Android官方指出的Android的数据存储方式总共有五种,分别是:Shared Preferences.网络存储.文件存储.外储存储.SQLite.但是我们知道一般这些存储都只是在单独的一个应用程序之中达到一个数据的共享,有时候我们需要操作其他应用程序的一些数据,例如我们需要操作系统里的媒体库.通讯录等,这时我们就可能通过ContentProvider来满足我们的需求了. 2.为什么要选择Conte