android serialport new 软件退出_基于Android9.0,了解Android启动流程

b7af0d56d67e34d4e52756e6e407f52c.png

先记住四个进程和三种方式。

**四个进程**

1.Launcher进程

2.system_server进程

3.App进程

4.Zygote进程

**三种方式**

1.Binder方式

2.Socket方式

3.Handler方式

点击桌面APP图标,Launcher调用startActivitySafely(Launcher进程)

```java

/**

* Default launcher application.

*/

public final class Launcher extends Activity

implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,

View.OnTouchListener {

....

/**

* Launches the intent referred by the clicked shortcut.

*

* @param v The view representing the clicked shortcut.

*/

public void onClick(View v) {

// Make sure that rogue clicks don't get through while allapps is launching, or after the

// view has detached (it's possible for this to happen if the view is removed mid touch).

...

Object tag = v.getTag();

if (tag instanceof ShortcutInfo) {

// Open shortcut

final Intent intent = ((ShortcutInfo) tag).intent;

int[] pos = new int[2];

v.getLocationOnScreen(pos);

intent.setSourceBounds(new Rect(pos[0], pos[1],

pos[0] + v.getWidth(), pos[1] + v.getHeight()));

boolean success = startActivitySafely(v, intent, tag);//注意这里

if (success && v instanceof BubbleTextView) {

mWaitingForResume = (BubbleTextView) v;

mWaitingForResume.setStayPressed(true);

}

} else if (tag instanceof FolderInfo) {

...

} else if (v == mAllAppsButton) {

...

}

}

```

```java

boolean startActivitySafely(View v, Intent intent, Object tag) {

boolean success = false;

try {

success = startActivity(v, intent, tag);//注意这里

} catch (ActivityNotFoundException e) {

...

}

return success;

}

```

接着看startActivity

```java

boolean startActivity(View v, Intent intent, Object tag) {

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//这里表示要在新的task中启动activity

try {

// Only launch using the new animation if the shortcut has not opted out (this is a

// private contract between launcher and may be ignored in the future).

//只有在快捷方式没有选择退出时才使用新动画启动(这是一个

//私有合同之间的启动和可能被忽略在未来)。//这是有道翻译的

//如果快捷方式尚未退出,则仅使用新动画启动(这是

//启动器之间的私人合同,将来可能会被忽略)。//这是google翻译的

//大概知道什么意思就行,不必纠结有道还是google

boolean useLaunchAnimation = (v != null) &&

!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);

UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE);

LauncherApps launcherApps = (LauncherApps)

this.getSystemService(Context.LAUNCHER_APPS_SERVICE);

if (useLaunchAnimation) {

ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,

v.getMeasuredWidth(), v.getMeasuredHeight());

if (user == null || user.equals(android.os.Process.myUserHandle())) {

// Could be launching some bookkeeping activity

startActivity(intent, opts.toBundle());//注意这里

} else {

launcherApps.startMainActivity(intent.getComponent(), user,

intent.getSourceBounds(),

opts.toBundle());

}

} else {

...

}

return true;

} catch (SecurityException e) {

...

}

return false;

}

```

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

表示要在一个新的Task(任务栈)中启动这个Activity

Android系统中的每一个Activity都位于一个Task中,一个Task可以包含多个Activity,同一个Activity也可能有多个实例。 在AndroidManifest.xml中,我们可以通过android:launchMode来控制Activity在Task中的实例。

在startActivity的时候,我们也可以通过setFlag 来控制启动的Activity在Task中的实例。

在Task之外,还有一层容器,这个容器应用开发者和用户可能都不会感觉到或者用到,但它却非常重要,那就是Stack,Android系统中的多窗口管理,就是建立在Stack的数据结构上的。 一个Stack中包含了多个Task,一个Task中包含了多个Activity(Window)。

Launcher进程采用Binder向system_server进程发起startActivity请求,现在我们从最熟悉的startAcitivty开始分析(养成先有点,再有线,最后成面的思路,防止看完懵逼)。startActivity有好几种重载方式,跟源码一层一层跟下去,发现最后都会调用startActivityForResult。

```java

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,

@Nullable Bundle options) {

if (mParent == null) {

options = transferSpringboardActivityOptions(options);

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

}

...

} else {

...

}

}

```

我们这里关注mParent == null条件的即可,mParent 代表的是ActivityGroup,ActivityGroup最开始被用来在一个界面中嵌入多个子Activity,但是在API13中已经被废弃了,系统推荐采用 Fragment来代替ActivityGroup。

继续跟下去,查看mInstrumentation.execStartActivity,mInstrumentation是Instrumentation的实例,Instrumentation拥有跟踪application及activity的功能。

```java

public ActivityResult execStartActivity(

Context who, IBinder contextThread, IBinder token, Activity target,

Intent intent, int requestCode, Bundle options) {

IApplicationThread whoThread = (IApplicationThread) contextThread;

...

try {

...

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) {

...

}

return null;

}

```

最后调用

ActivityManager.getService().startActivity来完成启动。

点进ActivityManager.getService()查看

```java

/**

* @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;

}

};

```

发现是一个IActivityManager的单例。

IActivityManager是一个Binder接口,而ActivityManagerService(AMS)继承IActivityManager.Stub,IActivityManager.Stub是IActivityManager.aidl生成的接口类,Android8.0开始,把一些Binder代码转化为了AIDL模板方式。这里生成一个Launcher进程的AMS代理,AMS是IActivityManager的具体实现,所以这里,就需要去看AMS的startActivity方法。(在system_server进程中调用)

```java

@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) {

return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,

resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,

true /*validateIncomingUser*/);

}

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,

boolean validateIncomingUser) {

enforceNotIsolatedCaller("startActivity");

userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,

Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

// TODO: Switch to user app stacks here.

return mActivityStartController.obtainStarter(intent, "startActivityAsUser")

.setCaller(caller)

.setCallingPackage(callingPackage)

.setResolvedType(resolvedType)

.setResultTo(resultTo)

.setResultWho(resultWho)

.setRequestCode(requestCode)

.setStartFlags(startFlags)

.setProfilerInfo(profilerInfo)

.setActivityOptions(bOptions)

.setMayWait(userId)

.execute();

}

```

mActivityStartController是ActivityStartController的实例

```java

/**

* @return A starter to configure and execute starting an activity. It is valid until after

* {@link ActivityStarter#execute} is invoked. At that point, the starter should be

* considered invalid and no longer modified or used.

*/

ActivityStarter obtainStarter(Intent intent, String reason) {

return mFactory.obtain().setIntent(intent).setReason(reason);

}

```

mFactory是ActivityStarter的一个内部接口,我们再来看看ActivityStarter的execute方法

```java

/**

* Starts an activity based on the request parameters provided earlier.

* @return The starter result.

*/

int execute() {

try {

// TODO(b/64750076): Look into passing request directly to these methods to allow

// for transactional diffs and preprocessing.

if (mRequest.mayWait) {

return startActivityMayWait(mRequest.caller, mRequest.callingUid,

...

} else {

return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,

...

}

} finally {

...

}

}

```

因为之前调用了ActivityStarter的setMayWait方法

```java

ActivityStarter setMayWait(int userId) {

mRequest.mayWait = true;

mRequest.userId = userId;

return this;

}

```

所以,这里的mRequest.mayWait为true,继续跟

```java

private 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, SafeActivityOptions options, boolean ignoreTargetSecurity,

int userId, TaskRecord inTask, String reason,

boolean allowPendingRemoteAnimationRegistryLookup) {

...

final ActivityRecord[] outRecord = new ActivityRecord[1];

int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,

voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,

callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,

ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,

allowPendingRemoteAnimationRegistryLookup);

Binder.restoreCallingIdentity(origId);

...

return res;

}

}

```

接着,连进三个startActivity的重载方法,然后到startActivityUnchecked,后面一串调用startActivityUnchecked->ActivityStackSupervisor.resumeFocusedStackTopActivityLocked->ActivityStack.resumeTopActivityUncheckedLocked->ActivityStack.resumeTopActivityUncheckedLocked->ActivityStack.resumeTopActivityInnerLocked->ActivityStackSupervisor.startSpecificActivityLocked

```java

void startSpecificActivityLocked(ActivityRecord r,

boolean andResume, boolean checkConfig) {

// 该活动的应用程序是否已经在运行?

ProcessRecord app = mService.getProcessRecordLocked(r.processName,

r.info.applicationInfo.uid, true);

getLaunchTimeTracker().setLaunchTime(r);

if (app != null && app.thread != null) {//ProcessRecord类型的对象记录了进程相关的信息,app.thread为IApplicationThread,这两个对象在进程为创建时,都是为null的

try {

...

realStartActivityLocked(r, app, andResume, checkConfig);//热启动走向,注意这里,进入分支二

return;

} catch (RemoteException 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);//冷启动走向,注意这里,进入分支一

}

```

---

### 分支一:进程还没有创建

ActivityManagerService.startProcessLocked

```java

@GuardedBy("this")

final ProcessRecord startProcessLocked(String processName,

ApplicationInfo info, boolean knownToBeDead, int intentFlags,

String hostingType, ComponentName hostingName, boolean allowWhileBooting,

boolean isolated, boolean keepIfLarge) {

return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,

hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,

null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,

null /* crashHandler */);//这里以socket的方式,进行跨进程通信。通知zygote fork出app进程

}

@GuardedBy("this")

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) {

long startTime = SystemClock.elapsedRealtime();

ProcessRecord app;

if (!isolated) {//这里为false

app = getProcessRecordLocked(processName, info.uid, keepIfLarge);

checkTime(startTime, "startProcess: after getProcessRecord");

...

} else {

// If this is an isolated process, it can't re-use an existing process.

//如果这是一个独立的进程,它就不能重用现有的进程。

app = null;

}

...

if (app == null) {

checkTime(startTime, "startProcess: creating new process record");

app = newProcessRecordLocked(info, processName, isolated, isolatedUid);

//创建并锁定

...

} else {

// If this is a new package in the process, add the package to the list

...

}

...

checkTime(startTime, "startProcess: stepping in to startProcess");

final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);//注意这里

checkTime(startTime, "startProcess: done starting proc!");

return success ? app : null;

}

```

进入startProcessLocked

```java

@GuardedBy("this")

private final boolean startProcessLocked(ProcessRecord app,

String hostingType, String hostingNameStr, String abiOverride) {

return startProcessLocked(app, hostingType, hostingNameStr,

false /* disableHiddenApiChecks */, abiOverride);

}

/**

* @return {@code true} if process start is successful, false otherwise.

*/

@GuardedBy("this")

private final boolean startProcessLocked(ProcessRecord app, String hostingType,

String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {

...

return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,

runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,

startTime);//注意这里

} catch (RuntimeException e) {

...

return false;

}

}

@GuardedBy("this")

private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,

ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,

String seInfo, String requiredAbi, String instructionSet, String invokeWith,

long startTime) {

app.pendingStart = true;

app.killedByAm = false;

app.removed = false;

app.killed = false;

final long startSeq = app.startSeq = ++mProcStartSeqCounter;

app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);

if (mConstants.FLAG_PROCESS_START_ASYNC) {

...

final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,

app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,

requiredAbi, instructionSet, invokeWith, app.startTime);//注意这里

synchronized (ActivityManagerService.this) {

handleProcessStartedLocked(app, startResult, startSeq);

}

...

});

return true;

} else {

...

final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,

uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,

invokeWith, startTime);//注意这里

handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,

startSeq, false);

...

return app.pid > 0;

}

}

```

继续看startProcess

```java

private ProcessStartResult startProcess(String hostingType, String entryPoint,

ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,

String seInfo, String requiredAbi, String instructionSet, String invokeWith,

long startTime) {

...

if (hostingType.equals("webview_service")) {

...

} else {

startResult = Process.start(entryPoint,

app.processName, uid, uid, gids, runtimeFlags, mountExternal,

app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,

app.info.dataDir, invokeWith,

new String[] {PROC_START_SEQ_IDENT + app.startSeq});

}

...

return startResult;

...

}

```

继续看Process.start

```java

public static final ProcessStartResult start(final String processClass,

final String niceName,

int uid, int gid, int[] gids,

int runtimeFlags, int mountExternal,

int targetSdkVersion,

String seInfo,

String abi,

String instructionSet,

String appDataDir,

String invokeWith,

String[] zygoteArgs) {

return zygoteProcess.start(processClass, niceName, uid, gid, gids,

runtimeFlags, mountExternal, targetSdkVersion, seInfo,

abi, instructionSet, appDataDir, invokeWith, zygoteArgs);

}

```

zygoteProcess为ZygoteProcess实例,继续看ZygoteProcess的start

```java

public final Process.ProcessStartResult start(final String processClass,

...{

try {

return startViaZygote(processClass, niceName, uid, gid, gids,

runtimeFlags, mountExternal, targetSdkVersion, seInfo,

abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,

zygoteArgs);

} catch (ZygoteStartFailedEx ex) {

...

}

}

```

继续

```java

private Process.ProcessStartResult startViaZygote(final String processClass,

...

synchronized(mLock) {

return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);//注意这里,以及注意openZygoteSocketIfNeeded这个方法

}

}

```

继续

```java

@GuardedBy("mLock")

private static Process.ProcessStartResult zygoteSendArgsAndGetResult(

ZygoteState zygoteState, ArrayList<String> args)

throws ZygoteStartFailedEx {

...

// Should there be a timeout on this?

Process.ProcessStartResult result = new Process.ProcessStartResult();//注意这里

...

return result;

} catch (IOException ex) {

...

}

}

```

这里的openZygoteSocketIfNeeded(),内部实现Zygote通过Socket的方式,与system_sever连接,最后调用native层方法nativeForkAndSpecialize,fork一个新的进程。(这条线,自行阅读、跟踪源码。记住:点成线,线成面,切勿贪心,否则一脸懵逼。)

至此APP进程创建完成,接着会通过反射执行APP进程的ActivityThread的main方法,这个main方法是APP进程的入口。

```java

public static void main(String[] args) {

...

Looper.prepareMainLooper();//创建一个主线程的Looper

...

ActivityThread thread = new ActivityThread();

thread.attach(false, startSeq);//注意这里

if (sMainThreadHandler == null) {

sMainThreadHandler = thread.getHandler();

}

...

Looper.loop();//开启循环

throw new RuntimeException("Main thread loop unexpectedly exited");

}

```

继续看attach

```java

private void attach(boolean system, long startSeq) {

sCurrentActivityThread = this;

mSystemThread = system;

if (!system) {

...

final IActivityManager mgr = ActivityManager.getService();//获取AMS在app客户端的代理对象

try {

mgr.attachApplication(mAppThread, startSeq);//注意这里,app进程挂起,执行system进程AMS的attachApplication

} catch (RemoteException ex) {

throw ex.rethrowFromSystemServer();

}

...

}

```

继续attachApplication

```java

@Override

public final void attachApplication(IApplicationThread thread, long startSeq) {

synchronized (this) {

...

attachApplicationLocked(thread, callingPid, callingUid, startSeq);//注意这里

...

}

}

```

继续attachApplicationLocked

```java

@GuardedBy("this")

private final boolean attachApplicationLocked(IApplicationThread thread,

int pid, int callingUid, long startSeq) {

...

if (app.isolatedEntryPoint != null) {

// This is an isolated process which should just call an entry point instead of

// being bound to an application.

thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);

} else if (app.instr != null) {

thread.bindApplication(processName, appInfo, providers,

app.instr.mClass,

profilerInfo, app.instr.mArguments,

app.instr.mWatcher,

app.instr.mUiAutomationConnection, testMode,

mBinderTransactionTrackingEnabled, enableTrackAllocation,

isRestrictedBackupMode || !normalMode, app.persistent,

new Configuration(getGlobalConfiguration()), app.compat,

getCommonServicesLocked(app.isolated),

mCoreSettingsObserver.getCoreSettingsLocked(),

buildSerial, isAutofillCompatEnabled);

} else {

thread.bindApplication(processName, appInfo, providers, null, profilerInfo,

null, null, null, testMode,

mBinderTransactionTrackingEnabled, enableTrackAllocation,

isRestrictedBackupMode || !normalMode, app.persistent,

new Configuration(getGlobalConfiguration()), app.compat,

getCommonServicesLocked(app.isolated),

mCoreSettingsObserver.getCoreSettingsLocked(),

buildSerial, isAutofillCompatEnabled);

}

...

} catch (Exception e) {

...

}

// See if the top visible activity is waiting to run in this process...

//看看顶部可见的活动是否正在等待在这个进程中运行……

if (normalMode) {

try {

if (mStackSupervisor.attachApplicationLocked(app)) {//注意这里

didSomething = true;

}

} catch (Exception e) {

..

}

}

...

return true;

}

```

thread为IApplicationThread,这里system进程调用app进程的ActivityThrad.ApplicationThread的bindApplication,同时

继续看看

```java

public final void bindApplication(String processName, ApplicationInfo appInfo,

List<ProviderInfo> providers, ComponentName instrumentationName,

ProfilerInfo profilerInfo, Bundle instrumentationArgs,

IInstrumentationWatcher instrumentationWatcher,

IUiAutomationConnection instrumentationUiConnection, int debugMode,

boolean enableBinderTracking, boolean trackAllocation,

boolean isRestrictedBackupMode, boolean persistent, Configuration config,

CompatibilityInfo compatInfo, Map services, Bundle coreSettings,

String buildSerial, boolean autofillCompatibilityEnabled) {

...

sendMessage(H.BIND_APPLICATION, data);

}

```

局势越来越明朗了,继续sendMessage,连着几个重载,最后到H的H.BIND_APPLICATION

```java

case BIND_APPLICATION:

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");

AppBindData data = (AppBindData)msg.obj;

handleBindApplication(data);//注意这里

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

break;

```

继续handleBindApplication

```java

private void handleBindApplication(AppBindData data) {

...

final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,

appContext.getClassLoader(), false, true, false);//拿到并保存了ApplicationInfo所包含的代码和资源的目录

final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);//创建要启动Activity的上下文环境

try {

final ClassLoader cl = instrContext.getClassLoader();

mInstrumentation = (Instrumentation)

cl.loadClass(data.instrumentationName.getClassName()).newInstance();//用类加载器来创建Instrumentation实例

} catch (Exception e) {

...

}

final ComponentName component = new ComponentName(ii.packageName, ii.name);//该类保存了Activity类名和包名

mInstrumentation.init(this, instrContext, appContext, component,

data.instrumentationWatcher, data.instrumentationUiAutomationConnection);

...

} else {

mInstrumentation = new Instrumentation();

mInstrumentation.basicInit(this);

}

app = data.info.makeApplication(data.restrictedBackupMode, null);//这里生成Application

...

try {

mInstrumentation.callApplicationOnCreate(app);//注意这里

} catch (Exception e) {

...

}

} finally {

...

}

...

}

```

继续

```java

public void callApplicationOnCreate(Application app) {

app.onCreate();//执行Application的onCreate()方法

}

```

这里Application由data.info.makeApplication生成,http://data.info为LoadedApk对象,所以这里看LoadedApk的makeApplication

```java

public Application makeApplication(boolean forceDefaultAppClass,

Instrumentation instrumentation) {

...

ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);

app = mActivityThread.mInstrumentation.newApplication(

cl, appClass, appContext);

appContext.setOuterContext(app);

} catch (Exception e) {

...

}

mActivityThread.mAllApplications.add(app);

mApplication = app;

if (instrumentation != null) {//这里传入的instrumentation为null,data.info.makeApplication(data.restrictedBackupMode, null);

try {

instrumentation.callApplicationOnCreate(app);

} catch (Exception e) {

...

}

}

...

return app;

}

```

记得attachApplicationLocked里面,还调用了ActivityStackSupervisor的attachApplicationLocked

```java

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {

final String processName = app.processName;

...

if (realStartActivityLocked(activity, app,

top == activity /* andResume */, true /* checkConfig */)) {//注意这里

didSomething = true;

}

} catch (RemoteException e) {

...

}

}...

return didSomething;

}

```

继续看realStartActivityLocked,的后面接着下面的**分支二**

### 分支二:进程已经创建

ActivityStackSupervisor.realStartActivityLocked

```java

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,

boolean andResume, boolean checkConfig) throws RemoteException {

...

// Create activity launch transaction.

final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,

r.appToken);

clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),

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, mService.isNextTransitionForward(),

profilerInfo));

// Set desired final state.

final ActivityLifecycleItem lifecycleItem;

if (andResume) {

lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());

} else {

lifecycleItem = PauseActivityItem.obtain();

}

clientTransaction.setLifecycleStateRequest(lifecycleItem);

// Schedule transaction.执行Activity启动事务

mService.getLifecycleManager().scheduleTransaction(clientTransaction);//注意这里

...

return true;

}

```

mService是AMS,getLifecycleManager()返回一个ClientLifecycleManager对象

```java

/**

* Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.

* @param transaction A sequence of client transaction items.

* @throws RemoteException

*

* @see ClientTransaction

*/

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {

final IApplicationThread client = transaction.getClient();

transaction.schedule();

if (!(client instanceof Binder)) {

// If client is not an instance of Binder - it's a remote call and at this point it is

// safe to recycle the object. All objects used for local calls will be recycled after

// the transaction is executed on client in ActivityThread.

transaction.recycle();

}

}

```

scheduleTransaction内部调用ClientTransaction.schedule

```java

/**

* Schedule the transaction after it was initialized. It will be send to client and all its

* individual parts will be applied in the following sequence:

* 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work

* that needs to be done before actually scheduling the transaction for callbacks and

* lifecycle state request.

* 2. The transaction message is scheduled.

* 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes

* all callbacks and necessary lifecycle transitions.

*/

public void schedule() throws RemoteException {

mClient.scheduleTransaction(this);

}

```

这里mClient就是执行ClientTransaction.obtain(app.thread,r.appToken);时,传进来的app.thread,也就是IApplicationThread。

```java

/** Obtain an instance initialized with provided params. */

public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {

ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);

if (instance == null) {

instance = new ClientTransaction();

}

instance.mClient = client;

instance.mActivityToken = activityToken;

return instance;

}

```

IApplicationThread的具体实现为ActivityThread的内部类ApplicationThread,兜兜转转,又回到了ApplicationThread

```java

@Override

public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {

ActivityThread.this.scheduleTransaction(transaction);

}

```

ActivityThread的内部没有scheduleTransaction()方法,看父类的ClientTransactionHandler

```java

/** Prepare and schedule transaction for execution. */

void scheduleTransaction(ClientTransaction transaction) {

transaction.preExecute(this);

sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);

}

```

ClientTransactionHandler的sendMessage是一个抽象方法,所以去实现类ActivityThread去找,最终调用ActivityThread的sendMessage方法

```java

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;//ActivityThread.H.EXECUTE_TRANSACTION

msg.obj = obj;

msg.arg1 = arg1;

msg.arg2 = arg2;

if (async) {

msg.setAsynchronous(true);

}

mH.sendMessage(msg);

}

```

mH是Handler的实例,继续跟mH的EXECUTE_TRANSACTION

```java

case EXECUTE_TRANSACTION:

final ClientTransaction transaction = (ClientTransaction) msg.obj;

mTransactionExecutor.execute(transaction);

if (isSystem()) {

// Client transactions inside system process are recycled on the client side

// instead of ClientLifecycleManager to avoid being cleared before this

// message is handled.

transaction.recycle();

}

// TODO(lifecycler): Recycle locally scheduled transactions.

break;

```

mTransactionExecutor为TransactionExecutor的实例,继续

```java

public void execute(ClientTransaction transaction) {

final IBinder token = transaction.getActivityToken();

log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

executeCallbacks(transaction);

executeLifecycleState(transaction);

mPendingActions.clear();

log("End resolving transaction");

}

```

调用了executeCallbacks和executeLifecycleState,继续

```java

/** Cycle through all states requested by callbacks and execute them at proper times. */

@VisibleForTesting

public void executeCallbacks(ClientTransaction transaction) {

...

final int size = callbacks.size();

for (int i = 0; i < size; ++i) {

final ClientTransactionItem item = callbacks.get(i);

log("Resolving callback: " + item);

final int postExecutionState = item.getPostExecutionState();

final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,

item.getPostExecutionState());

if (closestPreExecutionState != UNDEFINED) {

cycleToPath(r, closestPreExecutionState);

}

item.execute(mTransactionHandler, token, mPendingActions);

item.postExecute(mTransactionHandler, token, mPendingActions);

if (r == null) {

// Launch activity request will create an activity record.

r = mTransactionHandler.getActivityClient(token);

}

if (postExecutionState != UNDEFINED && r != null) {

// Skip the very last transition and perform it by explicit state request instead.

final boolean shouldExcludeLastTransition =

i == lastCallbackRequestingState && finalState == postExecutionState;

cycleToPath(r, postExecutionState, shouldExcludeLastTransition);

}

}

}

/** Transition to the final state if requested by the transaction. */

private void executeLifecycleState(ClientTransaction transaction) {

...

// Cycle to the state right before the final requested state.

cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

// Execute the final transition with proper parameters.

lifecycleItem.execute(mTransactionHandler, token, mPendingActions);

lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);

}

```

executeCallbacks和executeLifecycleState都调用了cycleToPath,继续

```java

/** Transition the client between states. */

@VisibleForTesting

public void cycleToPath(ActivityClientRecord r, int finish) {

cycleToPath(r, finish, false /* excludeLastState */);

}

/**

* Transition the client between states with an option not to perform the last hop in the

* sequence. This is used when resolving lifecycle state request, when the last transition must

* be performed with some specific parameters.

*/

private void cycleToPath(ActivityClientRecord r, int finish,

boolean excludeLastState) {

final int start = r.getLifecycleState();

log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);

final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);

performLifecycleSequence(r, path);//注意这里

}

```

继续跟进performLifecycleSequence

```java

/** Transition the client through previously initialized state sequence. */

private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {

final int size = path.size();

for (int i = 0, state; i < size; i++) {

state = path.get(i);

log("Transitioning to state: " + state);

switch (state) {

case ON_CREATE://注意这里

mTransactionHandler.handleLaunchActivity(r, mPendingActions,

null /* customIntent */);

break;

case ON_START:

mTransactionHandler.handleStartActivity(r, mPendingActions);

break;

case ON_RESUME:

mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,

r.isForward, "LIFECYCLER_RESUME_ACTIVITY");

break;

case ON_PAUSE:

mTransactionHandler.handlePauseActivity(r.token, false /* finished */,

false /* userLeaving */, 0 /* configChanges */, mPendingActions,

"LIFECYCLER_PAUSE_ACTIVITY");

break;

case ON_STOP:

mTransactionHandler.handleStopActivity(r.token, false /* show */,

0 /* configChanges */, mPendingActions, false /* finalStateRequest */,

"LIFECYCLER_STOP_ACTIVITY");

break;

case ON_DESTROY:

mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,

0 /* configChanges */, false /* getNonConfigInstance */,

"performLifecycleSequence. cycling to:" + path.get(size - 1));

break;

case ON_RESTART:

mTransactionHandler.performRestartActivity(r.token, false /* start */);

break;

default:

throw new IllegalArgumentException("Unexpected lifecycle state: " + state);

}

}

}

```

mTransactionHandler为传入的ClientTransactionHandler,其handleLaunchActivity为抽象方法,其子类ActivityThread实现了该方法

```java

/**

* Extended implementation of activity launch. Used when server requests a launch or relaunch.

*/

@Override

public Activity handleLaunchActivity(ActivityClientRecord r,

PendingTransactionActions pendingActions, Intent customIntent) {

...

final Activity a = performLaunchActivity(r, customIntent);

...

return a;

}

```

继续performLaunchActivity

```java

/** Core implementation of activity launch. */

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

ActivityInfo aInfo = r.activityInfo;//获取ActivityInfo类

if (r.packageInfo == null) {

r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,

Context.CONTEXT_INCLUDE_CODE);// 获取APK文件描述LoadedApk,LoadedApk在构造时,拿到并保存了ApplicationInfo所包含的代码和资源的目录

}

ComponentName component = r.intent.getComponent();//获取要启动的Activity的ComponentName类,该类保存了Activity类名和包名

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 activity = null;

try {

java.lang.ClassLoader cl = appContext.getClassLoader();// 用类加载器来创建Activity实例

activity = mInstrumentation.newActivity(

cl, component.getClassName(), r.intent);

StrictMode.incrementExpectedActivityCount(activity.getClass());

r.intent.setExtrasClassLoader(cl);

r.intent.prepareToEnterProcess();

...

} catch (Exception e) {

...

}

try {

Application app = r.packageInfo.makeApplication(false, mInstrumentation);// 创建Application,makeApplication方法内部会调用创建Application的onCreate()

...

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);// 初始化Activity,在attach方法中会创建window对象并与Activity关联

...

if (r.isPersistable()) {

mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);

} else {

mInstrumentation.callActivityOnCreate(activity, r.state);

}

...

}

...

} catch (SuperNotCalledException e) {

...

} catch (Exception e) {

...

}

return activity;

}

```

r.isPersistable()

```java

public boolean isPersistable() {

return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS;

}

```

继续走Instrumentation的callActivityOnCreate(activity, r.state, r.persistentState);

```java

/**

* Perform calling of an activity's {@link Activity#onCreate}

* method. The default implementation simply calls through to that method.

* @param activity The activity being created.

* @param icicle The previously frozen state (or null) to pass through to

* @param persistentState The previously persisted state (or null)

*/

public void callActivityOnCreate(Activity activity, Bundle icicle,

PersistableBundle persistentState) {

prePerformCreate(activity);

activity.performCreate(icicle, persistentState);//注意这里

postPerformCreate(activity);

}

```

继续,Activity.performCreate

```java

final void performCreate(Bundle icicle, PersistableBundle persistentState) {

mCanEnterPictureInPicture = true;

restoreHasCurrentPermissionRequest(icicle);

if (persistentState != null) {

onCreate(icicle, persistentState);

} else {

onCreate(icicle);

}

writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");

mActivityTransitionState.readState(icicle);

mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(

com.android.internal.R.styleable.Window_windowNoDisplay, false);

mFragments.dispatchActivityCreated();

mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());

}

```

终于看到了熟悉的onCreate,感动,Read The Fucking Source Code。

---

### 总结:

- 先弄清楚,APP的启动流程。至于流程中涉及的Binder、Socket、Handler、反射等,后续再慢慢展开学习、了解

- 胖子有什么理解错误的,欢迎大家指出来,一起讨论、学习、进步

- 胖子文笔不怎么好,第一次写博客,尽量一次走一条路,岔路后续再慢慢补齐

- 写博客,对了解、学习、加深源码内部机制,有很大的帮助

- 期待胖子的第二篇[《Android消息机制》](基于Android9.0,了解Android消息机制)

---

### 参考文献

[Android 9.0 点击桌面应用图标,启动Activity的过程分析](CSDN-个人空间)

[android点击桌面App图标activity启动流程](Android启动过程 - 左手指月 - 博客园)

Android开发艺术探索<br/>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/431960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】使用命令行方式创建和启动android模拟器

原文网址&#xff1a;http://blog.csdn.net/tiandinilv/article/details/8953001 1、Android模拟器介绍 Android中提供了一个模拟器来模拟ARM核的移动设备。Android的模拟器是基于QEMU开发的&#xff0c;QEMU是一个有名的开源虚拟机项目&#xff08;详见http://bellard.org/qem…

LPC1768的SPI通讯

SPI是一种全双工串行接口&#xff0c;可处理多个连接到指定总线上的主机和从机。在数据传输过程中总线上只能有一个主机和一个从机通信。在数据传输中&#xff0c;主机总是会向从机发送一帧8到16个位的数据&#xff0c;而从机也总会向主机发送一帧字节数据 使用代码如下 void S…

文本显示变量_几千个IO状态显示.十几分钟搞定实例

工程上常会在一个或者数个界面中对所有IO点监控&#xff0c;很多小伙伴用一一映射的传统方法来实现&#xff0c;在超小型项目中实用性较强&#xff0c;在稍微大一点的项目中实现起来效率低还经常出错。本文旨在分享有价值的实际经验&#xff0c;供小伙伴们参考。在实现监控前要…

TabBarController创建及使用方法简介

TabBarController创建及使用方法简介 大致讲解一下TabBarController的创建过程&#xff1a; 首先&#xff0c;我们需要一些视图&#xff0c;如创建UIControllerView类型的view1&#xff0c;view2&#xff0c;view3. 然后&#xff0c;我们需要创建 一个UITabBarController类型的…

华为gre隧道全部跑静态路由

最终实现&#xff1a; 1、pc1能用nat上网ping能pc3 2、pc1能通过gre访问pc2 3、全部用静态路由做&#xff0c;没有用ospf&#xff0c;如果要用ospf&#xff0c;那么两边除了路由器上跑ospf&#xff0c;核心交换机也得用ospf r2配置&#xff1a; acl number 3000 rule 5 deny…

数组与串,串的实现,KMP,BF算法

数组是一种常用的数据结构&#xff0c;高级语言头提供了支持数组的基本操作&#xff0c;而且数组也是构成其他数据结构的重要组成。 数组是N个相同元素的构成的占用一块地址连续的内存单元的有限序列。 数组的任一个元素都可以用在数组的位置来表示。 数组与线性表区别&#xf…

结对开发——求最大值

一、题目&#xff1a; 返回一个整数数组中最大子数组的和。 要求&#xff1a; 1.输入一个整形数组&#xff0c;数组里有正数也有负数。 2.数组中连续的一个或多个整数组成一个子数组&#xff0c;每个子数组都有一个和。 3.求所有子数组的和的最大值。要求时间复杂度为O(n)。 二…

浏览器获取设备信息_一条命令获取 IE 浏览器保存网站的账号和密码信息

渗透攻击红队一个专注于红队攻击的公众号大家好&#xff0c;这里是 渗透攻击红队 的第 41 篇文章&#xff0c;本公众号会记录一些我学习红队攻击的复现笔记(由浅到深)&#xff0c;不出意外每天一更Powershell内网渗透一直以来都是一个热门话题&#xff0c;试想在一个大型的内网…

(转) 一步一步学习ASP.NET 5 (四)- ASP.NET MVC 6四大特性

转发&#xff1a;微软MVP 卢建晖 的文章&#xff0c;希望对大家有帮助。原文&#xff1a;http://blog.csdn.net/kinfey/article/details/44459625 编者语 &#xff1a; 昨晚写好的文章居然csdn不审核&#xff0c;这个也难怪人&#xff0c;但自己比较忙没办法。分享继续&#xf…

win10 python 调用模块_python常识系列14--gt;python通过jpype模块调用jar包

前言能坚持一件事&#xff0c;本身就是一种很了不起的才华。一、jpype模块是什么&#xff1f;能够让 python 代码方便地调用 Java 代码的工具二、jpype模块安装安装和其它模块没区别&#xff0c;但是注意模块名 是 jpype1 &#xff0c;后面有个1pip install jpype1三、jpype模块…

mysql 载入主体时出错_mysql遇到load data导入文件数据出现1290错误的解决方案

错误出现情景在cmd中使用mysql命令&#xff0c;学生信息表添加数据。使用load data方式简单批量导入数据。准备好文本数据&#xff1a; xueshengxinxi.txt 文件 数据之间以tab键进行分割执行 “load data infile 文本数据路径 into table tab_load_data” 弹出错误。#load d…

【原创】Kakfa utils源代码分析(一)

Kafka.utils&#xff0c;顾名思义&#xff0c;就是一个工具套件包&#xff0c;里面的类封装了很多常见的功能实现——说到这里&#xff0c;笔者有一个感触&#xff1a;当初为了阅读Kafka源代码而学习了Scala语言&#xff0c;本以为Kafka的实现会用到很多函数编程(Functional Pr…

redhad yum 安装mysql_redhat7通过yum安装mysql5.7.17教程

rhel/centos系列linux操作系统自身没有mysql的源&#xff0c;需要自行下载安装。本文介绍如何安装mysql5.7.x数据库。第一步&#xff1a;下载源[rootclient ~]# wget http://repo.mysql.com/mysql57-community-release-el7-8.noarch.rpm注意&#xff1a;选择mysql57-community-…

codechef Polo the Penguin and the Tree

一般xor 的题目都是用trie解决。 那这道题是在树上的trie; 首先&#xff1a;从root1,遍历树得到1到所有节点的xor 值。 然后对于每个点我们把其插入二进制树中。 对于每一个点查找其二进值异或值最大的数 依次遍历下来。 注意&#xff1a;边的数量开两倍以上&#xff0c;RE很多…

mysql主从和dump_MySQL主从同步--原理及实现(一)

1、什么是mysql主从同步&#xff1f;当master(主)库的数据发生变化的时候&#xff0c;变化会实时的同步到slave(从)库。2、主从同步有什么好处&#xff1f;水平扩展数据库的负载能力。容错&#xff0c;高可用。Failover(失败切换)/High Availability数据备份。3、主从同步的原理…

解密多媒体封装解封装框架

上一篇文章我们搭好了环境并编译出所需的ffmpeg库&#xff0c;本篇我们讨论如何利用ffmpeg提供的API函数进行多媒体文件的解封装&#xff08;demux&#xff09;过程。在讲解之前&#xff0c;我们需要了解一些基本的多媒体文件知识&#xff0c;大虾请飘过。 容器格式&#xff1a…

bzoj 3611

和BZOJ消耗站一样&#xff0c;先将那个询问的简图构建出来&#xff0c;然后就是简单的树形DP。 &#xff08;倍增数组开小了&#xff0c;然后就狂WA&#xff0c;自己生成的极限数据深度又没有那么高&#xff0c;链又奇迹般正确&#xff09; 1 #include <cstdio>2 #includ…

vscode添加源文件_VSCode自制的IDE编译多个源文件

文/EdwardVSCode的预定义变量我们上一篇文章中讲述了如何将MinGW工具嵌入到VSCode文本编辑器中&#xff0c;在这个配置的过程中&#xff0c;我们只需要通过修改VSCode生成的“luanch.json”和“task.json”两个JSON文件中的特定字段&#xff0c;就可以实现开发环境的搭建。那么…

mysql+自动还原备份_Mysql 自动备份与恢复

自动备份MySql 5.0有三个方案&#xff1a;备份方案一&#xff1a; 通过 mysqldump命令,直接生成一个完整的 .sql 文件Step 1: 创建一个批处理(说明&#xff1a;root 是mysql默认用户名, aaaaaa 是mysql密码, bugtracker 是数据库名)------------mySql_backup.bat--------------…

Web Service 学习

1. Web services 平台的元素&#xff1a; SOAP (简易对象访问协议) UDDI (通用描述、发现及整合) WSDL (Web services 描述语言)1.1 什么是 SOAP&#xff1f; 基本的 Web services 平台是 XML HTTP。 SOAP 指简易对象访问协议 SOAP 是一种通信协议 SOAP 用于应用程序之间的通信…