[Android]從Launcher開始啟動App流程源碼分析



以下內容為原創,歡迎轉載,轉載請注明
來自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5017056.html

從Launcher開始啟動App流程源碼分析

com.android.launcher.Launcher就是我們的Launcher頁面了,可以看到Launcher其實也是一個Activity

public final class Launcher extends Activity implements View.OnClickListener, OnLongClickListener {
	// ...
}

既然是Activity,那當然也會有onCreateonResume等生命周期了,按照邏輯,應該會去加載所有App,以網格的布局顯示在頁面上,果然,在onResume看到了這個方法:

@Override
protected void onResume() {
    super.onResume();
    if (mRestoring) {
        startLoaders();
    }
    // ...
}

看方法名就可以猜到這個方法就是用來加載所有App信息的,進入這個方法:

private void startLoaders() {
	boolean loadApplications = sModel.loadApplications(true, this, mLocaleChanged);
	sModel.loadUserItems(!mLocaleChanged, this, mLocaleChanged, loadApplications);
	mRestoring = false;
}

這里調用sModelLauncherModel類型)的loadUserItems方法去加載數據了,sModel明顯屬於Model層,進入loadUserItems方法:

void loadUserItems(boolean isLaunching, Launcher launcher, boolean localeChanged,
            boolean loadApplications) {
	// ...
		mDesktopItemsLoaded = false;
        mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged, loadApplications,
                isLaunching);
        mDesktopLoaderThread = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
        mDesktopLoaderThread.start();
	// ...
}

然后使用DesktopItemsLoadermDesktopLoaderThread線程中加載,:

private class DesktopItemsLoader implements Runnable {
	// ...
	public void run() {
		// ...
		final Cursor c = contentResolver.query(LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
		// ...
		final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
		final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
		final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
		final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE);
		final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
		final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE);
		final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE);
		final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
		final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
		final int appWidgetIdIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.APPWIDGET_ID);
		final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
		final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
		final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
		final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
		final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
		final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
		final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE);
		// ...
		// 通過launcher回調返回數據
		launcher.onDesktopItemsLoaded(uiDesktopItems, uiDesktopWidgets);
		// ...
	}
	// ...
}

然后我們回到LauncheronDesktopItemsLoaded方法:

void onDesktopItemsLoaded(ArrayList<ItemInfo> shortcuts, ArrayList<LauncherAppWidgetInfo> appWidgets) {
	// ...
	bindDesktopItems(shortcuts, appWidgets);
}

繼續進入bindDesktopItems方法:

private void bindDesktopItems(ArrayList<ItemInfo> shortcuts, ArrayList<LauncherAppWidgetInfo> appWidgets) {
	// ...
	mBinder = new DesktopBinder(this, shortcuts, appWidgets, drawerAdapter);
    mBinder.startBindingItems();
}

進入startBindingItems方法:

public void startBindingItems() {
	// ...
	obtainMessage(MESSAGE_BIND_ITEMS, 0, mShortcuts.size()).sendToTarget();
}

這里使用了Handler發送消息,進入HandlerhandleMessage方法:

@Override
public void handleMessage(Message msg) {
	// ...
	switch (msg.what) {
		// ...
		case MESSAGE_BIND_ITEMS: {
			launcher.bindItems(this, mShortcuts, msg.arg1, msg.arg2);
            break;
        }
		// ...
	}
}

接收到消息之后調用bindItems方法:

private void bindItems(Launcher.DesktopBinder binder, ArrayList<ItemInfo> shortcuts, int start, int count) {
	// ...
	case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
	case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
		final View shortcut = createShortcut((ApplicationInfo) item);
		workspace.addInScreen(shortcut, item.screen, item.cellX, item.cellY, 1, 1, !desktopLocked);
	// ...
}

這里我們只考慮app或者app快捷方式的情況,文件夾和widgets暫時不考慮。app或者app快捷方式實質上都是進入了這個邏輯中,調用createShortcut方法:

// 重載方法,最終都會調用這個方法
View createShortcut(int layoutResId, ViewGroup parent, ApplicationInfo info) {
	// ...
	TextView favorite = (TextView) mInflater.inflate(layoutResId, parent, false);
	// ...
	favorite.setCompoundDrawablesWithIntrinsicBounds(null, info.icon, null, null);
	favorite.setText(info.title);
	favorite.setTag(info);
	favorite.setOnClickListener(this);
	// ...
}

這里首先inflater出item的布局,然后設置textOnClickListener,還有tag,這個tag是ApplicationInfo,里面包含了各種App信息,是從App的AndroidManifest.xml<application>標簽中解析出來的。既然設置了點擊事件,顯然,點擊后應該會打開對應的App才對。所以繼續看onClick方法:

public void onClick(View v) {
    Object tag = v.getTag();
    if (tag instanceof ApplicationInfo) {
        // Open shortcut
        final Intent intent = ((ApplicationInfo) tag).intent;
        startActivitySafely(intent);
    } else if (tag instanceof FolderInfo) {
        handleFolderClick((FolderInfo) tag);
    }
}

點擊App就會通過startActivitySafely方法使用剛才設置的tag,也就是ApplicationInfo中的intent進行跳轉:

void startActivitySafely(Intent intent) {
	intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
	// ...
	startActivity(intent);
	// ...
}



然后我們來看看打開某個app的時候整個流程是怎么走的。接着上面的的startActivity()方法走:

public void startActivity(Intent intent, @Nullable Bundle options) {
	// ...
	if (options != null) {
		startActivityForResult(intent, -1, options);
	} else {
	    startActivityForResult(intent, -1);
	}
	// ...
}

可以看到,不管你是調用了startActivity還是startActivityForResult方法,startActivityForResult方法,並且如果是調用的startActivity,則默認requestCode就是-1,所以如果你想調用startActivityForResult的時候,注意不能把requestCode設置為-1,否則它的效果就跟startActivity一樣了,不會再回調onActivityResult!,再看看startActivityForResult的實現:

public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
	Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, this,
            intent, requestCode, options);
    // ...
}

可以看到,Activity內部是使用mInstrumentationInstrumentation類型)執行execStartActivity方法來實現Activity跳轉的,執行完畢后會返回一個Instrumentation.ActivityResult

然后查看Instrumentation::execStartActivity

public ActivityResult execStartActivity(
	// ...
	int result = ActivityManagerNative.getDefault()
        .startActivity(whoThread, who.getBasePackageName(), intent,
                intent.resolveTypeIfNeeded(who.getContentResolver()),
                token, target != null ? target.mEmbeddedID : null,
                requestCode, 0, null, options);
	// ...
}

首先通過ActivityManagerNative.getDefault()獲得一個IActivityManager的實現類:

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

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
	protected IActivityManager create() {
		// 通過Binder IPC獲取ActivityManager(IBinder)
        IBinder b = ServiceManager.getService("activity");
        // ...
        IActivityManager am = asInterface(b);
        // ...
        return am;
    }
};

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

先通過Binder IPC的方式從服務端獲取一個Activity Manager,然后通過ActivityManagernative封裝成一個代理ActivityManagerProxy對象,然后調用startActivity也是使用了Binder IPC進行與服務器端的通信,(整個Android系統的通信機制使用了大量的Binder IPC,這個以后再專門討論這個吧),接着,我們進入到了com.android.server.am.ActivityManagerServicestartActivity方法:

@Override
public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options, UserHandle.getCallingUserId());
}

接下來的調用鏈:

-> startActivityAsUser
-> startActivityMayWait
-> startActivityLocked
-> startActivityUncheckedLocked
-> targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options)
-> mStackSupervisor.resumeTopActivitiesLocked(this, r, options)
-> resumeTopActivityInnerLocked(prev, options);
-> mStackSupervisor.startSpecificActivityLocked(next, true, true)

startSpecificActivityLocked方法如下:

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
	// ...
	if (app != null && app.thread != null) {
		// ...
		realStartActivityLocked(r, app, andResume, checkConfig);
		return;
	}
	// ...
	mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true);
}

首先從mService找出對應需要啟動Activity的進程(通過進程名字和uid,進程名字可以在AndroidManifest.xml中配置)如果可以獲取到,說明這個Activity所屬的進程已經存在了,也就是說app已經在運行了,那就會調用realStartActivityLocked,否則,如果該Activity所在的App是第一次啟動,則會調用mService.startProcessLocked方法:

final ProcessRecord startProcessLocked(/*...*/){
	// ...
	startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
	// ...
}

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
	// ...
	app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
	// ...
	if (app == null) {
		app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
	}
	// ...
}

private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
	// ...
	// entryPoint表示一個類,它用來作為新創建的進程的主入口,會調用這個類的靜態main方法,這個參數在startProcessLocked方法中會被檢查重置,如果是null的話,就默認是android.app.ActivityThread。
	if (entryPoint == null) entryPoint = "android.app.ActivityThread";
	// ...
	Process.ProcessStartResult startResult = Process.start(entryPoint,
            app.processName, uid, uid, gids, debugFlags, mountExternal,
            app.info.targetSdkVersion, app.info.seinfo, requiredAbi, 
            instructionSet, app.info.dataDir, entryPointArgs);
	// ...	
}

這3個重載方法做的事情就是,先根據進程名字調用getProcessRecordLocked()獲取ProcessRecord,如果ProcessRecord不存在,則調用newProcessRecordLocked()方法建立一個ProcessRecord,並且新的ProcessRecord綁定了ApplicationInfouid等信息,但后進入第三個重載方法,執行新建、啟動進程。

再看Process::start的實現:

public static final ProcessStartResult start(/*...*/){
	// ...
	return startViaZygote(processClass, niceName, uid, gid, gids,
              debugFlags, mountExternal, targetSdkVersion, seInfo,
              abi, instructionSet, appDataDir, zygoteArgs);
	// ...
}

接下來就是通過Zygote進程fork一個新的進程作為app的進程。這里要需要講的一個參數是processClass,這個參數表示一個類,它用來作為新創建的進程的主入口,會調用這個類的靜態main方法,這個參數在startProcessLocked方法中會被檢查重置,如果是null的話,就默認是android.app.ActivityThread

現在App的進程也創建成功了,就會進入android.app.ActivityThread的靜態的main中:

public static void main(String[] args) {
	// ...
	// 初始化主線程Looper
	Looper.prepareMainLooper();
	// ...
	ActivityThread thread = new ActivityThread();
    thread.attach(false);	
	// ...
	// 啟動消息循環
	Looper.loop()
	// ...
}

然后創建了一個ActivityThread,說明每當一個新的app進程被創建,都會對應一個新的ActivityThread實例,然后調用它的attach方法:

private void attach(boolean system) {
	// ...
	if (!system) {
		// ...
		final IActivityManager mgr = ActivityManagerNative.getDefault();
		// ...
		mgr.attachApplication(mAppThread);
		// ...
	}else{
		// ...
	}
	// ...
}

然后再次通過Binder IPC調用ActivityManagerProxyattachApplication,傳入的ApplicationThread(Binder)參數用於在服務端進行回調通信。最后進入ActivityManagerService::attachApplication,再調用attachApplicationLocked(thread, callingPid)

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
	// ...
	app = mPidsSelfLocked.get(pid);
	// ...
	app.makeActive(thread, mProcessStats);
    app.curAdj = app.setAdj= -100;
    app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
    app.forcingToForeground = null;
    updateProcessForegroundLocked(app, false, false);
    app.hasShownUi = false;
    app.debugging = false;
    app.cached = false;
    app.killedByAm = false;
	// ...
	thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked());
	// ...
	if (normalMode) {
	    try {
	        if (mStackSupervisor.attachApplicationLocked(app)) {
	            didSomething = true;
	        }
	    } catch (Exception e) {
	        Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
	        badApp = true;
	    }
	}
	// ...
}

首先,通過pid獲取剛剛創建的進程,然后對app進行一些初始化工作,然后調用bindApplication遠程調用客戶端ActivityThread::bindApplication,再通過Handler調用到ActivityThread::handleBindApplication方法:

private void handleBindApplication(AppBindData data) {
	// ...
	final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
	if (data.instrumentationName != null) {
		// ...
		mInstrumentationPackageName = ii.packageName;
        mInstrumentationAppDir = ii.sourceDir;
        mInstrumentationSplitAppDirs = ii.splitSourceDirs;
        mInstrumentationLibDir = ii.nativeLibraryDir;
        mInstrumentedAppDir = data.info.getAppDir();
        mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
        mInstrumentedLibDir = data.info.getLibDir();

        ApplicationInfo instrApp = new ApplicationInfo();
        instrApp.packageName = ii.packageName;
        instrApp.sourceDir = ii.sourceDir;
        instrApp.publicSourceDir = ii.publicSourceDir;
        instrApp.splitSourceDirs = ii.splitSourceDirs;
        instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
        instrApp.dataDir = ii.dataDir;
        instrApp.nativeLibraryDir = ii.nativeLibraryDir;
        LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                appContext.getClassLoader(), false, true, false);
        ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
        // ...
java.lang.ClassLoader cl = instrContext.getClassLoader();
        mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        mInstrumentation.init(this, instrContext, appContext, new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
        // ...
	}else{
		mInstrumentation = new Instrumentation();
	}
	// ...
	Application app = data.info.makeApplication(data.restrictedBackupMode, null);
    mInitialApplication = app;
	// ...
	mInstrumentation.callApplicationOnCreate(app);
	// ...
}

首先,創建一個當前App的Context,然后如果data.instrumentationName != null,則初始化Instrumentation相關的變量,並創建InstrumentationApplicationInfo等對象來創建InstrumentationContext,然后創建Instrumentation對象,並調用它的init方法進行初始化。如果data.instrumentationName == null,則new一個Instrumentation(在一個進程中只會有一個Instrumentation實例)然后創建Application對象,並調用它的onCreate方法,這樣Application就會被回調了。

然后我們回到ActivityManagerService::attachApplicationLocked方法,遠程執行完thread.bindApplication方法之后,接下來會調用mStackSupervisor.attachApplicationLocked(app)方法:

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
	// ...
	ActivityRecord hr = stack.topRunningActivityLocked(null);
	// ...
	realStartActivityLocked(hr, app, true, true)
	// ...
}

先通過topRunningActivityLocked從堆棧頂端獲取要啟動的Activity,然后realStartActivityLocked(hr, app, true, true)

final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
	// ...
	app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
	// ...
}

繼續通過Binder IPC遠程調用scheduleLaunchActivity方法,然后進入ActivityThreadscheduleLaunchActivity方法中,然后通過Handler進入handleLaunchActivity方法:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent){
	// ...
	Activity a = performLaunchActivity(r, customIntent);
	
	handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed);
	// ...
}

先調用performLaunchActivity方法返回一個Activity,然后調用handleResumeActivity方法讓該Activity進入onResume狀態。所以很顯然在performLaunchActivity中肯定是生成了Activity實例,並調用了onCreate方法了,來看下代碼:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
	// ...
	ActivityInfo aInfo = r.activityInfo;
	if (r.packageInfo == null) {
	    r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
	            Context.CONTEXT_INCLUDE_CODE);
	}
	// ...
	java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
    activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
	// ...
	Context appContext = createBaseContextForActivity(r, activity);
	// ...
	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);
	// ...
	if (r.isPersistable()) {
     mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }
	// ...
	mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, r.persistentState);
	// ...
	mInstrumentation.callActivityOnPostCreate(activity, r.state, r.persistentState);
	// ...
}

首先,初始化LoadedApk,然后通過Instrumentation來創建一個Activity實例,通過createBaseContextForActivity方法創建一個Activity Context,調用activityattach方法,然后依次觸發該ActivityonCreateonRestoreInstanceStateonPostCreate等生命周期方法。

createBaseContextForActivity方法如下:

private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
	// ...
	ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, displayId, r.overrideConfig);
    appContext.setOuterContext(activity);
    Context baseContext = appContext;
	// ...
}

通過ContextImpl::createActivityContext創建的Context對象,可以發現,不論是System Context/App Context/Activity Context,這些Context都是通過ContextImpl生成的,具體這里再挖個坑先。

再繼續進入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) {
	// ...
	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;
	// ...
}

上面對ActivityActivityThreadInstrumentation等進行了綁定,所以說每個Activity都含有一個ActivityThread引用和一個Instrumentation引用,而ActivityThread實例和Instrumentation實例在一個進程中都只有一個實例,因為ActivityThread是在進程被創建成功后,進入ActivityThreadstatic main()時才會被創建,而Instrumentation則是在ActivityThread被創建后進行attach的之后被創建。


### 啟動應用流程所有方法鏈調用總結:
  • Activity::startActivity

  • Activity::startActivityForResult

  • Instrumentation::execStartActivity
    攜帶參數:

  1. who:from的Context
  2. contextThread:from的ActivityThreadApplicationThreadApplicationThread中可以通過Binder IPC提供給服務端回調Activity生命周期等操作(from的主線程)。
  3. mTokenBinder類型,用來標識from的Activity,可能為null。
  4. target:from的Activity(所以是用來接收跳轉結果的),如果不是從Activity跳轉則為null。
  5. intent:跳轉Intent。
  6. requestCode:如果是startActivity,則為-1。
  7. options:額外Bundle數據。
  • ActivityManagerProxy::startActivity()
    攜帶參數:
  1. caller:上面的contextThread,from主線程。
  2. callingPackage:from的Context包名。
  3. intent:跳轉Intent。
  4. resolvedType:跳轉Intent的MIME類型。
  5. resultTo:上面的tokenBinder類型,用來標識from的Activity。
  6. resultWho:from的Activity的mEmbeddedID(唯一標示字符串)
  7. requestCode:如果是startActivity,則為-1。
  8. startFlags:默認傳入為0。
  9. profilerInfo:默認傳入為null。
  10. options:額外Bundle數據。
  • ActivityManagerService::startActivity()(通過Binder IPC調用):
    攜帶參數跟上面一樣。

  • ActivityManagerService::startActivityAsUser
    攜帶參數包括ActivityManagerService::startActivity()所有的參數,最再加一個:

  1. userId:userId,根據給當前進程分配的Linux UID(這個UID可以用來讓上層系統服務進行身份識別和權限檢查)得到一個userId(如果不是多用戶,則直接返回0)。
  • ActivityStackSupervisor::startActivityMayWait()
    參數:
  1. caller:上面的caller/contextThread,from主線程。
  2. callingUid:調用用戶uid。
  3. callingPackage:from的Context包名。
  4. intent:跳轉Intent。
  5. resolvedType:跳轉Intent的MIME類型。
  6. voiceSession:傳null。
  7. voiceInteractor:傳null。
  8. resultTo:上面的resultTo/tokenBinder類型,用來標識from的Activity。
  9. resultWho:from的Activity的mEmbeddedID(唯一標示字符串)
  10. requestCode:如果是startActivity,則為-1。
  11. startFlags:傳null。
  12. profilerInfo:傳null。
  13. outResult:傳null。
  14. config:傳null。
  15. options:額外數據。
  16. ignoreTargetSecurity:false。
  17. userId:上面的userId,根據給當前進程分配的Linux UID(這個UID可以用來讓上層系統服務進行身份識別和權限檢查)得到一個userId(如果不是多用戶,則直接返回0)。
  18. iContainer:傳null。
  19. inTask:null。
  • ActivityStackSupervisor::startActivityLocked()
    參數:
  1. caller:上面的caller/contextThread,from主線程。
  2. intent:跳轉Intent。
  3. resolvedType:跳轉Intent的MIME類型。
  4. aInfoActivityInfo類型,解析from的Activity的Intent信息。
  5. voiceSession:傳null。
  6. voiceInteractor:傳null。
  7. resultTo:上面的resultTo/tokenBinder類型,用來標識from的Activity。
  8. resultWho:from的Activity的mEmbeddedID(唯一標示字符串)
  9. requestCode:如果是startActivity,則為-1。
  10. callingPackage:from的Context包名。
  11. startFlags:傳null。
  12. options:額外數據。
  13. ignoreTargetSecurity:false。
  14. componentSpecified:是否顯示指定了component
  15. outActivity:傳null。
  16. container:上面的iContainer,轉型成了ActivityContainer,還是null。
  17. inTask:null。
    在這個方法中,通過ProcessRecord callerApp = mService.getRecordForAppLocked(caller);獲取到之前創建的ProcessRecord,然后從Activity棧中根據resultTo/token獲取到對應from Activity的ActivityRecord(sourceRecord),然后__創建將要跳轉的Activity的ActivityRecord對象__(Token也是在這個時候生成的)。
  • ActivityStackSupervisor::startActivityUncheckedLocked()
    參數:
  1. rActivityRecord類型,就是ActivityStackSupervisor::startActivityLocked()中創建的將要跳轉的Activity的ActivityRecord對象。
  2. sourceRecord:就是ActivityStackSupervisor::startActivityLocked()方法獲取的from Activity的sourceRecord
  3. voiceSession:傳null。
  4. voiceInteractor:傳null。
  5. startFlags:傳null。
  6. doResume:傳true。
  7. options:額外數據。
  8. inTask:null。
    這個方法中有大量的代碼來處理task/stack等方面的邏輯,以后再仔細深入這個方法。
  • ActivityStrack::startActivityLocked()
    方法調用者:ActivityStack類型,
    targetStack:在ActivityStackSupervisor::startActivityUncheckedLocked()中確定的需要添加到的ActivityStack
    參數:
  1. rActivityRecord類型,就是ActivityStackSupervisor::startActivityLocked()中創建的跳轉的Activity的ActivityRecord對象。
  2. newTask:是否Intent是否設置了Intent.FLAG_ACTIVITY_NEW_TASK
  3. doResume:傳true。
  4. keepCurTransition:這個具體后面再研究,跟Intent的flag有關。
  5. options:額外數據。
    同樣,這個方法中有大量的代碼來處理task/stack等方面的邏輯,以后再仔細深入這個方法__(執行完這個方法后,ActivityRecord就會被真正加入到ActivityStack中)__。
  • ActivityStackSupervisor::resumeTopActivitiesLocked()
    參數:
  1. targetStack:在ActivityStackSupervisor::startActivityUncheckedLocked()中確定的需要添加到的ActivityStack
  2. targetActivityRecord類型,就是ActivityStackSupervisor::startActivityLocked()中創建的跳轉的Activity的ActivityRecord對象。
  3. targetOptions:額外數據。
  • ActivityStack::resumeTopActivityLocked()
    參數:
  1. prevActivityRecord類型,就是ActivityStackSupervisor::startActivityLocked()中創建的跳轉的Activity的ActivityRecord對象。
  2. options:額外數據。
  • ActivityStack::resumeTopActivityInnerLocked()
    參數:
  1. prevActivityRecord類型,就是ActivityStackSupervisor::startActivityLocked()中創建的跳轉的Activity的ActivityRecord對象。
  2. options:額外數據。
  • ActivityStackSupervisor::startSpecificActivityLocked()
    參數:
  1. r:最頂部沒有處於finishing的Activity,就是剛剛在startActivityLocked中加入的將要跳轉的ActivityRecord,通過topRunningActivityLocked(null)查找
  2. andResume:傳true
  3. checkConfig:傳true
  • ActivityManagerService::startProcessLocked()
    參數:
  1. processName:創建進程的名稱,就是ActivityStack::startSpecificActivityLocked()中的r.processName
  2. infoApplicationInfo,也是r.info.applicaitonInfo,具體可以查看ActivityStackSupervisor::startActivityLocked()中創建ActivityRecord的代碼。
  3. knownToBeDead:傳true。
  4. intentFlags:傳0。
  5. hostingType:傳字符串“activity”。
  6. hostingNameComponentName類型,intent中的Componentname
  7. allowWhileBooting:傳false。
  8. isolated:傳false
  9. keepIfLarge傳true
  • ActivityManagerService::startProcessLocked()(重載方法):
    參數包含上面所有,多了以下幾個:
  1. isolatedUid:傳0
  2. abiOverride:傳null
  3. entryPoint:傳null
  4. entryPointArgs傳null
  5. crashHandler傳null
    注意:在這個方法中,會創建新進程的ProcessRecord對象,並綁定ApplicationInfo等信息,這樣,啟動進程后進行bindApplicaiton的時候就可以根據進程PID獲取到所有的ApplicationInfo信息了。
  • ActivityManagerService::startProcessLocked()(重載方法):
    參數:
  1. appProcessRecord類型,創建的進程。
  2. hostingType:傳字符串“activity”。
  3. hostingNameStr:通過hostingName生成的字符串(包名 + "/" + 類的簡單類名)
  4. abiOverride:傳null
  5. entryPoint:傳null
  6. entryPointArgs傳null
  • Process.start()
    參數(省略部分參數):
  1. processClass:上面的entryPoint,但是並不是null了,而是android.app.ActivityThread,因為在ActivityManagerService::startProcessLocked()中被設置默認值了,它表示一個類,用來作為新創建的進程的主入口,會調用這個類的靜態main方法。所以啟動完這個進程就會進入ActivityThreadstatic main()方法。
  2. zygoteArgs:fork zygote進程時的參數。
  • ActivityThread::main()

  • ActivityThread::attach()

  • ActivityManagerProxy::attachApplication()
    參數:

  1. mAppThreadApplicationThread()類型,Binder,用來提供給AMS調用。
  • ActivityManagerService::attachApplication()
    參數:
  1. mAppThreadApplicationThread()類型,Binder,用來提供給AMS調用。
  • ActivityManagerService::attachApplicationLocked()
    參數:
  1. threadApplicationThread()類型,Binder,用來提供給AMS調用。上面的mAppThread
  2. pid:當前調用的進程PID。
  • IApplicationThread::bindApplication()
    方法調用調用者:上面的thread/mAppThread,Binder,用來提供給AMS調用。
    參數(省略部分參數):
  1. packageName:用的進程名字processName
  2. infoApplicationInfo類型,從ProcessRecord中的instrumentationInfo或者info,這個ApplicationInfo是在建立ProcessRecord時就保存了。
  • ActivityThread::bindApplication()
    參數:同上

  • ActivityThread::handleBindApplication()
    通過Handler調用。
    參數:

  1. dataAppBindData類型,里面包含的類型processNameprovidersinstrumentationNameinstrumentationArgsinstrumentationWatcherinstrumentationUiAutomationConnectionconfig等數據。

- `ActivityManagerService`中的`ActivityThread::bindApplication()`執行完畢之后
  • ActivityStackSupervisor::attachApplicationLocked()
    參數:
  1. app:新建的進程綁定的ProcessRecord
  • ActivityStackSupervisor::realStartActivityLocked()
    參數:
  1. rActivityRecord類型,topRunningActivityLocked從堆棧頂端獲取要啟動的Activity。
  2. app:新建的進程綁定的ProcessRecord
  3. andResume:傳入true
  4. checkConfig:傳入true
  • IApplicationThread::scheduleLaunchActivity()
    參數(部分):
  1. intent:將要啟動的ActivityRecord中的intent
  2. token:將要啟動的ActivityRecord中的token
  3. info:將要啟動的ActivityRecord中的ApplicationInfo
  • ActivityThread::scheduleLaunchActivity()
    Binder IPC調用,參數與IApplicationThread::scheduleLaunchActivity()相同。

  • ActivityThread::handleLaunchActivity()
    該方法通過Handler調用,參數同上。

  1. rActivityClientRecord類型,在ActivityThread::scheduleLaunchActivity()中封裝,包括的數據有token, ident, intent, activityInfo等等,但是LoadedApk是這時根據包名從ActivityThread中弱引用緩存中獲取的的。
  2. customIntent:null
  • ActivityThread::performLaunchActivity()
    參數與ActivityThread::handleLaunchActivity()相同。

  • Activity::attach()
    參數(部分):

  1. contextActivityThread::performLaunchActivity()中創建的Activity Context
  2. aThreadActivityThread類型,主線程,一個進程都共用一個。
  3. token:構建ActivityRecord時生成的token
  4. applicationApplication第一次的時候創建一遍。
  5. intent:將要啟動的ActivityRecord中的intent。
  6. infoActivityInfo類型,將要啟動的ActivityRecord中的ActivityInfo
  • Instrumentation::callActivityOnCreate()
    參數(部分):
  1. activityActivityThread::performLaunchActivity()中創建的Activity
  • Activity::performCreate()

  • Activity::onCreate()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM