1. 程式人生 > >Android Activity的啟動流程原始碼解析(8.0)

Android Activity的啟動流程原始碼解析(8.0)

一,寫在前面

       Activity是Android四大元件之一,用於直接跟使用者進行互動,本篇文章將介紹Activity的啟動流程。使用者啟動Activity的方式大致有兩種:一種是在桌面點選應用程式的圖示,進入應用程式的主介面;另一種是在應用程式中,進入一個新的Activity。前者,桌面其實是系統應用launcher的介面,點選應用程式圖示,會進行應用程式的主介面,實質是從一個應用的Activity進入另一個應用Activity。        因此,不管是從桌面進入應用主介面,還是在應用裡進入一個新的Activity,最終都會呼叫Activity$startActivity方法。        值得一提的是,Android 5.0,7.0等版本中啟動Activity的原始碼有點小差異,版本的升級只是對程式碼做了一些封裝,最終都會把啟動Activity的任務交給ApplicationThread來處理。

二,Activity工作流程的前半部分析

       檢視Activity$startActivity原始碼如下:
    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

    //繼續檢視

    @Override
    public void startActivity(Intent intent, @Nullable 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);
        }
    }
       其實Activity$startActivity有幾個其他過載的方法,但是最終都會執行到Activity$startActivityForResult方法。如果是呼叫startActivity(intent)啟動Activity,那麼requestCode引數則傳入-1,表示當前Activity啟動一個新的Activity後,不需要獲取新的Activity返回來的資料。關於呼叫startActivityForResult啟動Activity的情況,就不多介紹了,繼續下一步。        檢視Activity$startActivityForResult原始碼:
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable 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;
            }

            cancelInputsAndStartExitTransition(options);
            // 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);
            }
        }
    }
       第3行,mParent指的是ActivityGroup,可以在一個介面裡巢狀多個Activity。隨著版本的升級,在API13以後就廢棄掉了。        第5行,呼叫了方法Instrumentation$execStartActivity,因為mParent為null。        第6行,mMainThread是一個ActivityThread物件,該物件初始化在當前Activity的attach方法中。        attach方法是在啟動Activity之前被呼叫,本篇文章後面會給出解釋。attach方法主要是註冊一些介面,給一些變數初始化值,其中就建立了PhoneWindow的例項,為建立WindowManagerImpl物件做準備。通過WindowManager可以新增,刪除,更新視窗,從程式碼角度來說 ,增加,刪除,更新操作的是View。對WindowManager的不瞭解的,可以檢視文章Android 原始碼解析之WindowManager新增視窗。        前面提到mMainThread是一個ActivityThread物件,mMainThread.getApplicationThread()返回的是一個ApplicationThread物件,ApplicationThread是ActivityThread的內部類。        檢視ApplicationThread原始碼如下:
    public final class ActivityThread {
    
	final ApplicationThread mAppThread = new ApplicationThread();

	//...code

	private class ApplicationThread extends IApplicationThread.Stub {
	
		//...code
	}

    }
       ApplicationThread繼承了IApplicationThread.Stub,說明這裡Android使用了AIDL技術實現程序間通訊。當然完全也可以不用AIDL技術,而選擇手寫AIDL檔案自動生成的Java程式碼,在其他版本上就是這麼處理。 IApplicationThread是一個AIDl介面,繼承了IInterface介面;Stub是介面IApplicationThread的內部類,繼承了Binder類,實現了IApplicationThread介面。因此,ApplicationThread就是一個Binder物件,它重寫了IApplicationThread介面的抽象方法,這些重寫的方法一定會在某一刻,基於Binder機制被呼叫。至於,這一刻啥時候發生,在後面就知道啦,這裡就此打住~        回到Activity$startActivityForResult方法,第5行,呼叫了方法Instrumentation$execStartActivity。        檢視Instrumentation$execStartActivity的原始碼:
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;

        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
       第9行,ActivityManager.getService()返回的是什麼呢。        檢視ActivityManager$getService原始碼:
    /**
     * @hide
     */
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    //繼續檢視

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

	    //...code

    }
        變數IActivityManagerSingleton是一個Singleton物件,檢視Singleton原始碼如下:
public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}
       Singleton是一個抽象類,有一個抽象方法create()。有一個get()方法,內部通過單例模式建立T物件,呼叫create方法建立T物件,且只會建立一次T物件。        繼續檢視create方法的具體實現,IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE)獲取一個關聯了系統服務ActivityManagerService的Binder物件;IActivityManager.Stub.asInterface(b)返回一個IActivityManager的代理物件,基於Binder機制,通過呼叫代理物件的方法,使得系統服務ActivityManagerService對應的方法被呼叫。可以猜測ActivityManagerService肯定繼承了IActivityManager.Stub,事實也確實如此。        ActivityManagerService原始碼如下:
    public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
	
	//...code
	
    }
       回到Instrumentation$execStartActivity方法的第9行,ActivityManager.getService().startActivity(...),就是IActivityManager的代理物件呼叫了startActivity方法,通過Binder機制,它會使系統服務ActivityManagerService的startActivity方法被呼叫。因此,啟動Activity的操作就交給了系統服務ActivityManagerService來處理了。

三,啟動Activity的操作交給ActivityManagerService處理  

      檢視 ActivityManagerService$startActivity原始碼:
    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

    //繼續檢視

    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null,
                "startActivityAsUser");
    }
               檢視ActivityStarter原始碼如下:
final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask, String reason) {
	    
	    //...code

	    int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask, reason);

	    //...code	    
}


	//繼續檢視

int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask, String reason) {
	    
	//...code    

	    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                container, inTask);
	//...code    
}


       //繼續檢視

private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {

	//...code

	doPendingActivityLaunchesLocked(false);

	//...code
}


     //繼續檢視
final void doPendingActivityLaunchesLocked(boolean doResume) {
	//...code

                startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
                        null, null /*outRecords*/);

	//...code
}    


    //繼續檢視

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
       //...code

            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        
       //...code 
} 


    //繼續檢視

 // Note: This method should only be called from {@link startActivity}.
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
	//...code 

	mSupervisor.resumeFocusedStackTopActivityLocked();
	
	//...code 
}
       變數mSupervisor是一個ActivityStackSupervisor物件。        檢視ActivityStackSupervisor原始碼如下:
boolean resumeFocusedStackTopActivityLocked() {
        return resumeFocusedStackTopActivityLocked(null, null, null);
}

//繼續檢視

boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        //...code

	mFocusedStack.resumeTopActivityUncheckedLocked(null, null);

	//...code
}
               mFocusedStack是一個ActivityStack物件;        ActivityStack原始碼如下:
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
	//...code

	result = resumeTopActivityInnerLocked(prev, options);

	//...code

}

//繼續檢視

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
	//...code

	mStackSupervisor.startSpecificActivityLocked(next, true, true);

	//...code

}
       mSupervisor是一個ActivityStackSupervisor物件;        檢視ActivityStackSupervisor原始碼如下:
void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
	    
	//...code

	realStartActivityLocked(r, app, andResume, checkConfig);

	//...code

}

//繼續檢視

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
	//...code

	app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global and
                    // override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);

	//...code	    
}
       變數app是一個ProcessRecord物件,它的成員變數thread是IApplicationThread型別,因此app.thread是一個IApplicationThread的代理物件。        前面介紹ApplicationThread繼承了IApplicationThread.Stub,並提出ApplicationThread重寫介面IApplicationThread的抽象方法在哪裡被呼叫。有意思的是,app.thread呼叫scheduleLaunchActivity方法,通過Binder機制,會使ApplicationThread$scheduleLaunchActivity方法被呼叫。        於是,基於Binder機制,實現了一次程序間的通訊,將啟動Activity的操作交給了ApplicationThread類。

四,啟動Activity的操作,交給ApplicationThread來處理

       前面有介紹ApplicationThread是ActivityThread的內部類,因此ApplicationThread可以呼叫外部類ActivityThread的方法,也可以這樣理解,啟動Activity的操作交給了ActivityThread來處理。好了,下面開始進入主題啦。        檢視ApplicationThread$scheduleLaunchActivity方法原始碼如下:
	@Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            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;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
       第11行,建立了一個ActivityClientRecord物件,用於封裝啟動Activity需要的一些引數值。        第34行,呼叫ActivityThread$sendMessage方法,檢視其原始碼如下:
private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
}

//繼續檢視

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
}
       第19行,mH是一個H物件,類H是ActivityThread的內部類,並繼承了Handler。於是,啟動Activity的操作放在處理訊息的方法H$handleMessage中。 。        檢視H$handleMessage原始碼如下:
private class H extends Handler {

    //...code
	public void 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, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
    	
	//...code

}
       第9行,取出Message物件中的obj欄位,它是一個ActivityClientRecord物件;        第10行,呼叫ActivityThread$getPackageInfoNoCheck方法,返回一個LoadedApk物件,並將該物件封裝到ActivityClientRecord的packgeInfo欄位中。        第11行,呼叫ActivityThread$handleLaunchActivity方法啟動Activity;        檢視ActivityThread$handleLaunchActivity原始碼如下:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    //...

    Activity a = performLaunchActivity(r, customIntent);

    //...

    if (a != null) {
        //...

        handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
		    
        //...

    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
        try {
             ActivityManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
    }

}
       第4行,呼叫performLaunchActivity方法啟動Activity;        第11行,若a不為空,則呼叫handleResumeActivity方法,內部會呼叫Activity$onResume方法。具體的程式碼流程還是比較好跟的,由於不是本篇的重點,有興趣的哥們可以自己去研究。        第16行,當a為空,也就是建立Activity的例項出錯了,走else語句。ActivityManager.getService()前面已經分析過了,返回IActivityManager的代理物件,呼叫該代理物件的方法,會向系統服務ActivityManagerService傳送請求,基於Binder機制,最終會呼叫ActivityManagerService$finishActivity方法。        也就是說,當建立Activity例項出錯後,停止啟動Activity的具體操作交給ActivityManagerService來處理。        回到啟動Activity的流程,檢視ActivityThread$performLaunchActivity原始碼如下:
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);
        }

        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        
	    //...code

            java.lang.ClassLoader cl = appContext.getClassLoader();
            if (appContext.getApplicationContext() instanceof Application) {
                activity = ((Application) appContext.getApplicationContext())
                        .instantiateActivity(cl, component.getClassName(), r.intent);
            }
            if (activity == null) {
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
            }
            
	    //...code

            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            //...code

            if (activity != null) {
                
		//...code

                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, r.configCallback);

                //...code

                mInstrumentation.callActivityOnCreate(activity, r.state);

		//...code
	     }
   
        return activity;
}
       ActivityThread$performLaunchActivity方法的操作:        1,獲取要啟動的Activity的ComponentName物件:裡面包含了包名,類名相關的資訊;        2,建立Activity的上下文環境:即建立了ContextImpl物件;        3,建立Activity的例項:呼叫Instrumentation$newActivity方法,並使用類載入器建立Activity物件;        4,建立Application物件;        5,呼叫Activity$attach方法:初始化Activity類裡的一些資料;        6,啟動Activity:呼叫Instrumentation$callActivityOnCreate方法;        分析ActivityThread$performLaunchActivity方法:        步驟2,建立了Activity的上下文環境,ContextImpl是抽象類Context的實現類,有關Context的操作的具體實現,大多數由ContextImpl完成。        檢視ActivityThread$createBaseContextForActivity原始碼如下:
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {

	//...code

	ContextImpl appContext = ContextImpl.createActivityContext(
                this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
	
	//...code

	return appContext;
}
       繼續檢視ContextImpl$createActivityContext原始碼如下:
static ContextImpl createActivityContext(ActivityThread mainThread,
            LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
            Configuration overrideConfiguration) {
	    //...code

	    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
                activityToken, null, 0, classLoader);
	    
	   //...code 
}
        很顯然,最終建立了一個ContextImpl物件。         步驟3,建立了一個Activity的例項。         檢視Instrumentation$newActivity原始碼如下:
public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }
       通過ClassLoader建立Activity的例項。

       步驟4,建立了Application物件,具體分析往下看唄~        檢視LoadedApk$makeApplication方法原始碼如下:
public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

	Application app = null;

	//...

	app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
	
	//...

	mApplication = app;

	instrumentation.callApplicationOnCreate(app);
	//...

	return app;
}
        第3行,當mApplication不為null時,也就是Application物件已經存在時,直接返回mApplication。很顯然Application是一個單例物件,一個應用程式中只存在一個Application物件。
       第11行,當應用程式記憶體中沒有Application物件時,建立一個Application物件。跟Activity一樣,都是通過類載入器ClassLoader來建立例項。具體程式碼就不再展示,有興趣哥們可以去驗證。
       第16行,將Application物件app賦給欄位mApplication。        第18行,呼叫Application的onCreate方法。        檢視Instrumentation$callApplicationOnCreate方法原始碼:
    public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }
               步驟5,呼叫Activity$attach方法初始化資料。        檢視Activity$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, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(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;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
        if (voiceInteractor != null) {
            if (lastNonConfigurationInstances != null) {
                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
            } else {
                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                        Looper.myLooper());
            }
        }

        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }
       第8行,引數context:步驟2中建立的ContextImpl物件傳入的。attachBaseContext方法:給ContextWrapper的成員變數mBase設定值為ContextImpl物件。ContextWrapper是Context的一個子類,具體的程式碼流程感興趣的哥們可以去驗證~        第12行,建立了視窗物件PhoneWindow;        第13~15行,給視窗物件註冊監聽介面;        第23~37行,初始化一些變數的值;        第47行,通過視窗Window建立WindowManagerImpl的例項;        第54行,將47行建立的WindowManagerImpl的例項,設定給變數mWindowManager;        步驟6,呼叫Instrumentation$callActivityOnCreate方法啟動Activity。        檢視Instrumentation$callActivityOnCreate原始碼:
public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
}
       第3行,呼叫了Activity$performCreate方法。        檢視Activity$performCreate原始碼如下:
final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
}
       第3行,呼叫了Activity的onCreate方法啟動Activity,終於找到期待已久的onCreate方法啦~

       到這裡,Activity的啟動流程就分析完畢了^_^

相關推薦

Android Activity啟動流程原始碼解析(8.0)

一,寫在前面        Activity是Android四大元件之一,用於直接跟使用者進行互動,本篇文章將介紹Activity的啟動流程。使用者啟動Activity的方式大致有兩種:一種是在桌面點選應用程式的圖示,進入應用程式的主介面;另一種是在應用程式中,進入一個新的

Android 9.0Activity啟動流程原始碼分析

前言 熟悉Activity的啟動流程和執行原理是一個合格的應用開發人員所應該具備的基本素質,其重要程度就

Android中system server程序啟動流程原始碼解析 系統服務啟動

system server 前言 System Server fork SystemServer SystemServer.main() SystemServer.createSystemContext SystemSe

Android Activity啟動流程(基於Android8.0系統)

主要物件介紹 ActivityManagerService:負責系統中所有Activity的生命週期; Activi

Spring boot啟動流程原始碼解析

閱讀須知 版本:2.0.4 文章中使用/* */註釋的方法會做深入分析 正文 @SpringBootApplication public class BootApplication { public static void main(String[

Spring IOC容器啟動流程原始碼解析(一)——容器概念詳解及原始碼初探

目錄 1. 前言 1.1 IOC容器到底是什麼 IOC和AOP是Spring框架的核心功能,而IOC又是AOP實現的基礎,因而可以說IOC是整個Spring框架的基石。那麼什麼是IOC?IOC即控制反轉,通俗的說就是讓Spring框架來幫助我們完成物件的依賴管理和生命週期控制等等工作。從面向物件的角度來說,

Spring IOC容器啟動流程原始碼解析(四)——初始化單例項bean階段

目錄 1. 引言 2. 初始化bean的入口 3 嘗試從當前容器及其父容器的快取中獲取bean 3.1 獲取真正的beanName 3.2 嘗試從當前容器的快取中獲取bean 3.3 從父容器中查詢bean 3.4 解析bean的依賴 3.5 再一

Activity啟動流程原始碼分析(應用中)

在移動應用開發中,Android四大元件之一Activity是最常用的。很多介面,如:閃屏、主介面、次功能介面等都需要Activity來作為主要的載體;介面與介面之間,即不同的Activity之間也都存在跳轉切換,弄懂這其中跳轉切換原理,將有助於我們更好的理解A

Android Activity啟動流程分析

概述 Activity作為Android的四大元件之一,Android主要的介面組成部分,用於直接跟使用者進行互動操作,在面試中與Activity相關的知識也是經常被問到,如果你面試的高階崗位,那麼對Activity的啟動和繪製流程就必須的熟悉,本文將從Act

NioEventLoop啟動流程原始碼解析

NioEventLoop的啟動時機是在服務端的NioServerSocketChannel中的ServerSocketChannel初始化完成,且註冊在NioEventLoop後執行的, 下一步就是去繫結埠,但是在繫結埠前,需要完成NioEventLoop的啟動工作, 因為程式執行到這個階段為止,依然只有Ma

SpringSecurity啟動流程原始碼解析 | 部落格園新人第三彈

別辜負生命,別辜負自己。 楔子 前面兩期我講了SpringSecurity認證流程和SpringSecurity鑑權流程,今天是第三期,是SpringSecurity的收尾工作,講SpringSecurity的啟動流程。 就像很多電影拍火了之後其續作往往是前作的前期故事一樣,我這個第三期要講的Sprin

Activity啟動過程原始碼分析(Android 8.0

Activity啟動過程原始碼分析 本文來Activity的啟動流程,一般我們都是通過startActivity或startActivityForResult來啟動目標activity,那麼我們就由此出發探究系統是如何實現目標activity的啟動的。 startActivity(new Intent(con

Android原始碼分析 - Activity啟動流程

啟動Activity的方式 Activity有2種啟動的方式,一種是在Launcher介面點選應用的圖示、另一種是在應用中通過Intent進行跳轉。我們主要介紹與後者相關的啟動流程。 Intent intent = new Intent(this, TestActivity

Android 元件系列 -- Activity 啟動流程(9.0)

在學習完Android應用程式啟動過程原始碼分析,針對最新Android9.0的程式碼,以相應的順序再次學習。在9.0的版本中對於Activity的啟動流程上並沒有太大的變化,但是在程式碼層面,改動的卻很多。 流程概覽 以Launcher啟動APP為例: Lau

Android Launcher啟動應用程式流程原始碼解析

帶著問題看原始碼 點選桌面Launcher圖示後做了哪些工作? 應用程式什麼時候被建立的? Application和MainActivity的onCreate()方法什麼時候被呼叫的? 概述 在Android系統中,啟動四大元件中的任何一個都可以啟動應用程式。但絕大部分時候我們是通過點選Laun

Activity啟動流程,介面繪製到事件處理的整個流程(基於Android6.0原始碼)(2)

void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) { synchronized (this) { ...... mWindowAttributes

Android系統啟動流程(一)解析init進程啟動過程

option 寫入 android change failed miss 通知 target sna 前言 作為“Android框架層”這個大系列中的第一個系列,我們首先要了解的是Android系統啟動流程,在這個流程中會涉及到很多重要的知識點,這個系列我們就來一一講解它們

Android9.0 Activity啟動流程分析(二)

文章目錄 1、ActivityThread的main函式 2. AMS的attachApplication函式 2.1 Part-I 2.2 Part-II 2.2.1 ApplicationThread的bindApp

Android9.0 Activity啟動流程分析(一)

1、ActivityRecord、TaskRecord、ActivityStack和ActivityDisplay介紹   本篇文章是基於Android refs/tags/android-9.0.0_r8分支的程式碼進行分析的   在分析Activity啟動的原始碼之前先介紹一下Act

Android 外掛化分析(3)- Activity啟動流程

在真正分析外掛化技術前,我們必須瞭解一些必要的關於Android四大元件的相關知識。 以Activity為例,我們需要了解Activity啟動過程,才能有效的進行Hook實現外掛化。 以Android 8.1為例 我們啟動一個Activity通常會使用startActi