Activtiy

767 阅读24分钟

启动流程

一、Launcher 的 onPause 流程

既然要启动新的 APK 置于前台,那么当前活动必然要被切换到后台,所以首先涉及到的就是 Launcher 的 onPause() 流程。

回调接口 ItemClickHandler 会执行 onClick() 方法中的 startAppShortcutOrInfoActivity()。

接着调用Launcher的startActivitySafely() 方法。

Launcher接着调用父类 BaseDraggingActivity 的 startActivitySafely() 方法。在方法中添加标志,表示要在一个新的 Task 中启动这个 Activity。

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

最后调用 Activity.startActivity() 方法里面的startActivityForResult()方法。

startActivityForResult(intent, -1, options);

options 表示 Launcher 启动 Activity 时的动画效果。

在方法里面又掉用了mInstrumentation.execStartActivity() 方法。

Instrumentation.ActivityResult ar =  mInstrumentation.execStartActivity( 
this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);

mInstrumentation.execStartActivity() 方法中有一个 mMainThread.getApplicationThread() 参数,mMainThread 是 Activity 类的成员变量,它的类型是 ActivityThread,它代表的是应用程序的主线程。

public final class ActivityThread extends ClientTransactionHandler { 

final ApplicationThread mAppThread = new ApplicationThread(); 

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

public ApplicationThread getApplicationThread() { return mAppThread; } 

}

mMainThread.getApplicationThread() 获得的是 ActivityThread 内部成员变量 ApplicationThread,它是一个 Binder 对象。

Instrumentation 是 Android 系统中启动 Activity 的一个实际操作类,它用来监控应用程序和系统的交互。

在方法中调用 ActivityTaskManager.getService().startActivity() 方法。

int result = ActivityTaskManager.getService() .startActivity(whoThread, 
who.getBasePackageName(), intent, 
intent.resolveTypeIfNeeded(who.getContentResolver()), token, target, 
requestCode, 0, null, options);

看下 ActivityTaskManager.getService() 方法:

public class ActivityTaskManager { 

public static IActivityTaskManager getService() { 

return IActivityTaskManagerSingleton.get(); // 获取 IActivityTaskManager 单例
} 

private static final Singleton<IActivityTaskManager> 
IActivityTaskManagerSingleton = new Singleton<IActivityTaskManager>() { 

@Override 
protected IActivityTaskManager create() { 

final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE); 

return IActivityTaskManager.Stub.asInterface(b); 
} 

}; 
} 

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {}

我们发现 ActivityTaskManagerService 与 ActivityTaskManager 的 Binder 通信采用了 AIDL 的方式。

ActivityTaskManager.getService().startActivity() 方法实际上调用到了 ActivityTaskManagerService 的 startActivity() 方法。

下面看看 ActivityTaskManagerService 的 startActivity 方法,它跳转到startActivityAsUser() 方法。

ActivityStartController getActivityStartController() {
    return mActivityStartController;
}

return getActivityStartController()
.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId) // 设置了 mRequest.mayWait = true,后面会用到
.execute();
public class ActivityStartController { 

private final Factory mFactory; 

ActivityStarter obtainStarter(Intent intent, String reason) { 

// obtain()、setIntent()、setReason() 分别干了什么,下面一一说明 

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

}
}

这边用到了工厂模式,我们跟一下具体的处理流程。

mFactory.obtain() - -> DefaultFactory.obtain()

class ActivityStarter { 

interface Factory { 

void setController(ActivityStartController controller); 

ActivityStarter obtain(); 

void recycle(ActivityStarter starter); 

} 

// DefaultFactory 为实现类 

static class DefaultFactory implements Factory { 

@Override 
public ActivityStarter obtain() { 

ActivityStarter starter = mStarterPool.acquire(); 

if (starter == null) { 

// obtain() 方法最终返回的是 ActivityStarter 的实例 

starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor); 

} 

return starter; 

} } }

mFactory.obtain().setIntent() - -> ActivityStarter.setIntent()

class ActivityStarter { 

private Request mRequest = new Request(); 

ActivityStarter setIntent(Intent intent) { 

mRequest.intent = intent; // 为 mRequest 赋值 r

eturn this; 

} }

mFactory.obtain().setIntent(intent).setReason() - ->ActivityStarter.setReason()

class ActivityStarter { 

private Request mRequest = new Request(); 

ActivityStarter setReason(String reason) { 

mRequest.reason = reason; // 为 mRequest 赋值 

return this; 

} }

getActivityStartController().obtainStarter() 方法最终获得一个包含所有启动信息的 ActivityStarter 对象,然后作了各种赋值处理,最后执行 execute() 方法。

流程小结:

image.png

ActivityStarter.startActivityMayWait():

// 解析 Intent 的数据 
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 
0 /* matchFlags */, 
computeResolveFilterUid( callingUid, realCallingUid, mRequest.filterCallingUid));

// 收集 intent 中的相关信息
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

// 用于记录 Activity 的数据
final ActivityRecord[] outRecord = new ActivityRecord[1];

// 启动 Activity 
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, originatingPendingIntent, allowBackgroundActivityStart);

经过 3 次 startActivity() 调用,最终执行了 startActivityUnchecked() 方法,这个方法里会根据 启动标志位 和 Activity 启动模式 来决定如何启动一个 Activity。

// 初始化启动 Activity 的各种配置,会先重置再重新配置,其中包括 ActivityRecord、Intent 等 
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor, restrictedBgActivity); 

final int preferredWindowingMode = mLaunchParams.mWindowingMode; 

// 计算出启动的 FLAG,并将计算的值赋值给 mLaunchFlags 
computeLaunchingTaskFlags(); 

computeSourceStack(); 

// 将 mLaunchFlags 设置给 Intent,达到设定 Activity 的启动方式的目的 mIntent.setFlags(mLaunchFlags); 

// 获取是否有可以复用的 activity 
ActivityRecord reusedActivity = getReusableIntentActivity(); 

... ... 

// 可复用 Activity 不为空 
if (reusedActivity != null) { ... ... } 

... ... 

mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, 
mKeepCurTransition, mOptions);

// 调用 resumeFocusedStacksTopActivities() 方法 
mRootActivityContainer.resumeFocusedStacksTopActivities( mTargetStack, 
mStartActivity, mOptions);
// 调用 resumeTopActivityUncheckedLocked() 方法 
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
// 调用 resumeTopActivityInnerLocked() 方法
result = resumeTopActivityInnerLocked(prev, options);
// 先执行 startPausingLocked() 方法
pausing |= startPausingLocked(userLeaving, false, next, false);

// 执行 startSpecificActivityLocked() 方法
mStackSupervisor.startSpecificActivityLocked(next, true, true);

在 resumeTopActivityInnerLocked() 方法中会去判断是否有 Activity 处于 Resume 状态。

如果有的话会先让这个 Activity 执行 Pausing 过程(其实也就是本案例中 Launcher 的 onPause 流程),然后再执行 startSpecificActivityLocked 方法来启动需要启动的 Activity。

// 栈顶 Activity 执行 onPause() 方法退出 final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean pauseImmediately) { 

... ... 

ActivityRecord prev = mResumedActivity; 

... ... 

// 把 prev 赋值给 mPausingActivity,这个值在 Activity 启动过程中会用到, 
// 这边其实就是将 mResumedActivity 赋值给 mPausingActivity,就是我们的 Launcher。 
mPausingActivity = prev;

/* * 从 Android P 开始,引入了 ClientLifecycleManager 和 ClientTransactionHandler 来辅助 
* 管理 Activity 生命周期,它会发送 EXECUTE_TRANSACTION 消息到 ActivityThread.H 里面继续处理。 
* 通过 ClientLifecycleManager 的 scheduleTransaction() 方法把 PauseActivityItem * 事件加入到执行计划中,开始栈顶的 pausing 过程。 
* * ClientLifecycleManager getLifecycleManager() { 
* return mLifecycleManager; * } 
*/ 
mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(), prev.appToken, 
PauseActivityItem.obtain(
prev.finishing, userLeaving, prev.configChangeFlags, pauseImmediately));
// frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java 

class ClientLifecycleManager { 

void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) throws RemoteException { 

final ClientTransaction clientTransaction = transactionWithState(client, activityToken, stateRequest); 

scheduleTransaction(clientTransaction); 

} 

void scheduleTransaction(ClientTransaction transaction) throws RemoteException { 

final IApplicationThread client = transaction.getClient(); transaction.schedule(); 

if (!(client instanceof Binder)) { transaction.recycle(); } } } 

// frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java 

public class ClientTransaction implements Parcelable, ObjectPoolItem { 

/** Target client. */ 

private IApplicationThread mClient; 

public IApplicationThread getClient() { return mClient; } 

public void schedule() throws RemoteException { mClient.scheduleTransaction(this); } }

ClientTransaction.schedule() 方法的 mClient 是一个 IApplicationThread 类型,ActivityThread 的内部类 ApplicationThread 派生这个接口类并实现了对应的方法。所以直接跳转到 ApplicationThread 中的 scheduleTransaction() 方法。

// frameworks/base/core/java/android/app/ActivityThread.java 

public final class ActivityThread extends ClientTransactionHandler { 

private class ApplicationThread extends IApplicationThread.Stub { 

public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { 

ActivityThread.this.scheduleTransaction(transaction); } } }

流程小结: image.png

ActivityThread 类中并没有定义 scheduleTransaction() 方法,所以调用的是他父类 ClientTransactionHandler 的 scheduleTransaction() 方法。

// frameworks/base/core/java/android/app/ClientTransactionHandler.java 

public abstract class ClientTransactionHandler { 

abstract void sendMessage(int what, Object obj); 

/** Prepare and schedule transaction for execution. */ 
void scheduleTransaction(ClientTransaction transaction) { 
transaction.preExecute(this); 

// 调用了 sendMessage 方法,这个方法是一个抽象方法, 
// 它的实现是在 ClientTransactionHandler 派生类的 ActivityThread 中。
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); } }
// frameworks/base/core/java/android/app/ActivityThread.java 

public final class ActivityThread extends ClientTransactionHandler { 

// An executor that performs multi-step transactions. 

private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this); 

class H extends Handler { 

public void handleMessage(Message msg) { 

if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 

switch (msg.what) { 

case EXECUTE_TRANSACTION: 

final ClientTransaction transaction = (ClientTransaction) msg.obj; 

// Handler H 的实例接收到 EXECUTE_TRANSACTION 消息后调用 
// TransactionExecutor.execute() 方法切换 Activity 状态。 
mTransactionExecutor.execute(transaction); 

if (isSystem()) { 
transaction.recycle(); 
} 
// TODO(lifecycler): Recycle locally scheduled transactions. 
break; } } } 

void sendMessage(int what, Object obj) { 

sendMessage(what, obj, 0, 0, false); 
} 

private void sendMessage(int what, Object obj, int arg1) { 

sendMessage(what, obj, arg1, 0, false); 
} 

private void sendMessage(int what, Object obj, int arg1, int arg2) { 

sendMessage(what, obj, arg1, arg2, false); 
} 

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { 

Message msg = Message.obtain(); 
msg.what = what; 
msg.obj = obj;
msg.arg1 = arg1; 
msg.arg2 = arg2; 

if (async) { msg.setAsynchronous(true); } 

// ActivityThread.sendMessage() 方法会把消息发送给内部名字叫 H 的 Handler 
mH.sendMessage(msg); 
} }

前面讲解到:在 ActivityStack.startPausingLocked() 方法里面 scheduleTransaction() 传递的是 PauseActivityItem() 对象,所以 executeLifecycleState() 方法里调用的 lifecycleItem.execute() 方法其实就是 PauseActivityItem.execute()方法。

public class PauseActivityItem extends ActivityLifecycleItem { 
@Override 
public void execute(ClientTransactionHandler client, IBinder token, 
PendingTransactionActions pendingActions) { 
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 
// 跳转到 ActivityThread.handlePauseActivity 方法 
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions, "PAUSE_ACTIVITY_ITEM"); 
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 
} }
public final class ActivityThread extends ClientTransactionHandler { 
@Override 
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving, 
int configChanges, PendingTransactionActions pendingActions, String reason) { 
ActivityClientRecord r = mActivities.get(token); 
if (r != null) { 
if (userLeaving) { performUserLeavingActivity(r); } 
r.activity.mConfigChangeFlags |= configChanges; 
// 调用 performPauseActivity() 方法 
performPauseActivity(r, finished, reason, pendingActions); 
// Make sure any pending writes are now committed. 
if (r.isPreHoneycomb()) { QueuedWork.waitToFinish(); } 
mSomeActivitiesChanged = true; 
} } }
public final class ActivityThread extends ClientTransactionHandler { 
/** * Pause the activity. 
* @return Saved instance state for pre-Honeycomb apps if it was saved, 
{@code null} otherwise. 
*/ 
private Bundle performPauseActivity(ActivityClientRecord r, 
boolean finished, String reason, PendingTransactionActions pendingActions) { 
... ... 
performPauseActivityIfNeeded(r, reason); 
... ... 
} }
public final class ActivityThread extends ClientTransactionHandler { 
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) { 
if (r.paused) { 
// You are already paused silly... 
return; 
} 
reportTopResumedActivityChanged(r, false /* onTop */, "pausing"); 
try { 
r.activity.mCalled = false; 
mInstrumentation.callActivityOnPause(r.activity); // 关键方法 
} catch (SuperNotCalledException e) { throw e; } catch (Exception e) { 
if (!mInstrumentation.onException(r.activity, e)) { 
throw new RuntimeException("Unable to pause activity " + 
safeToComponentShortString(r.intent) + ": " + e.toString(), e); 
} } 
r.setState(ON_PAUSE); 
} }
public class Instrumentation { 
/** * Perform calling of an activity's {@link Activity#onPause} method. The 
* default implementation simply calls through to that method. 
* * @param activity The activity being paused. 
*/ 
public void callActivityOnPause(Activity activity) { 
activity.performPause(); // 直接调用 Activity.performPause 方法 
} }
public class Activity extends ContextThemeWrapper implements 
LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks2, 
Window.OnWindowDismissedCallback, WindowControllerCallback, 
AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient { 
final void performPause() { 
dispatchActivityPrePaused(); 
mDoReportFullyDrawn = false; 
mFragments.dispatchPause(); 
mCalled = false; 
onPause(); // 执行暂停方法 
writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause"); 
mResumed = false; 
if (!mCalled && getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { 
throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onPause()"); 
} 
dispatchActivityPostPaused(); 
} }

流程小结:

image.png

在启动一个 Activity 的时候最先被执行的是栈顶的 Activity 的 onPause() 方法。

Launcher 的 onPause() 流程分析完,接下来我们看看新进程的启动流程:startSpecificActivityLocked() 方法。在这个方法中会去根据 进程 和 线程 是否存在判断 App 是否已经启动。

如果已经启动,就会调用 ActivityTaskManagerService.realStartActivityLocked() 方法继续处理。

如果没有启动,则会调用 ActivityTaskManagerService.startProcessAsync() 方法创建新的进程,我们重点看下新应用进程的创建流程。

public class ActivityTaskManagerService extends IActivityTaskManager.Stub { 

void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean 
isTop, String hostingType) { 
try { 
// Post message to start process to avoid possible deadlock of calling into AMS with the 
// ATMS lock held. 
// Message 包含一个 ActivityManagerInternal::startProcess 方法 
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess, mAmInternal, 
activity.processName, activity.info.applicationInfo, knownToBeDead, isTop, h
ostingType, activity.intent.getComponent()); 
mH.sendMessage(m); 
} finally { Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); } } }
public abstract class ActivityManagerInternal { 
// 抽象方法,由 ActivityManagerService 内部类 LocalService 实现 
public abstract void startProcess(String processName, ApplicationInfo info, 
boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName); }
public class ActivityManagerService extends IActivityManager.Stub implements 
Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 
@VisibleForTesting 
public final class LocalService extends ActivityManagerInternal { 
@Override 
public void startProcess(String processName, ApplicationInfo info, boolean 
knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName) { 
try { 
synchronized (ActivityManagerService.this) { // 调用 startProcessLocked() 方法 
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */, new 
HostingRecord(hostingType, hostingName, isTop), 
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */, false /* 
isolated */, true /* keepIfLarge */); } 
} finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } } }

/** * Process management. */ 
final ProcessList mProcessList = new ProcessList(); 
@GuardedBy("this") 
final ProcessRecord startProcessLocked(String processName, ApplicationInfo 
info, boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord, int 
zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, boolean 
keepIfLarge) { 
return mProcessList.startProcessLocked(processName, info, knownToBeDead, 
intentFlags, hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 
/* isolatedUid */, keepIfLarge, null /* ABI override */, null /* entryPoint 
*/, null /* entryPointArgs */, null /* crashHandler */); 
}
public final class ProcessList { 
@GuardedBy("mService") 
final ProcessRecord startProcessLocked(String processName, ApplicationInfo 
info, boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord, int 
zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int 
isolatedUid, boolean keepIfLarge, String abiOverride, String entryPoint, 
String[] entryPointArgs, Runnable crashHandler) { 
// 调用 startProcessLocked() 方法 
final boolean success = startProcessLocked(app, hostingRecord, 
zygotePolicyFlags, abiOverride); 
} }

@GuardedBy("mService") 
final boolean startProcessLocked(ProcessRecord app, HostingRecord 
hostingRecord, int zygotePolicyFlags, String abiOverride) { 
// 调用 startProcessLocked() 方法 
return startProcessLocked(app, hostingRecord, zygotePolicyFlags, false /* 
disableHiddenApiChecks */, false /* disableTestApiChecks */, false /* 
mountExtStorageFull */, abiOverride); 
}

@GuardedBy("mService") 
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, int 
zygotePolicyFlags, boolean disableHiddenApiChecks, boolean 
disableTestApiChecks, boolean mountExtStorageFull, String abiOverride) { 
... ... 
try { 
... ... 
// 调用 startProcessLocked() 方法 
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids, 
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi, 
instructionSet, invokeWith, startTime); 
} catch (RuntimeException e) { 
Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e); mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false, false, true, false, false, app.userId, "start failure"); 
return false; 
} }
// 调用 startProcess() 方法 
final Process.ProcessStartResult startResult = startProcess(hostingRecord, 
entryPoint, app, uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, 
seInfo, requiredAbi, instructionSet, invokeWith, startTime); 

handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper, 
startSeq, false);
// 执行 Process.start() 方法 
startResult = Process.start(entryPoint, app.processName, uid, uid, gids, 
runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, 
instructionSet, app.info.dataDir, invokeWith, app.info.packageName, 
zygotePolicyFlags, isTopApp, app.mDisabledCompatChanges, new String[]
{PROC_START_SEQ_IDENT + app.startSeq});

到这里,我们就明白了:ActivityTaskManagerService.startProcessLocked() 方法经过多次跳转最终会通过 Process.start() 方法来为应用创建进程。

image.png

源码最后会执行到 ActivityThread.main() 方法,执行主线程的初始化工作。

public final class ActivityThread extends ClientTransactionHandler { 

public static void main(String[] args) { 
// 创建主线程 looper 
Looper.prepareMainLooper(); 
// 初始化 ActivityThread 
ActivityThread thread = new ActivityThread(); 
// attach 到系统进程 
thread.attach(false, startSeq); 
if (sMainThreadHandler == null) { 
sMainThreadHandler = thread.getHandler(); 
} 
// 主线程启动,进入循环状态 
Looper.loop(); 
throw new RuntimeException("Main thread loop unexpectedly exited"); 
} }
public final class ActivityThread extends ClientTransactionHandler { 
private void attach(boolean system, long startSeq) { 
sCurrentActivityThread = this; 
mSystemThread = system; 
if (!system) { 
... ... 
final IActivityManager mgr = ActivityManager.getService(); 
try { 
// 通过 ActivityManagerService 为这个应用绑定一个 Application 
mgr.attachApplication(mAppThread, startSeq); 
} catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } 
// 添加一个垃圾回收观察者,每当系统触发垃圾回收的时候就会在 run 方法里面 // 去计算应用使用了多少内存,如果超过总量的四分之三就会尝试释放内存 
BinderInternal.addGcWatcher(new Runnable() { 
@Override 
public void run() { 
if (!mSomeActivitiesChanged) { return; } 
Runtime runtime = Runtime.getRuntime(); 
long dalvikMax = runtime.maxMemory(); 
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); 
if (dalvikUsed > ((3*dalvikMax)/4)) { 
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) + " total=" + (runtime.totalMemory()/1024) + " used=" + (dalvikUsed/1024)); 
mSomeActivitiesChanged = false; 
try { 
ActivityTaskManager.getService().releaseSomeActivities(mAppThread); 
} catch (RemoteException e) { 
throw e.rethrowFromSystemServer(); 
} } } }); } else { ... ... } ... ... 
// 为根 View 添加 config 回调接收 config 变化相关的信息 
ViewRootImpl.addConfigCallback(configChangedCallback); 
} }
public class ActivityManagerService extends IActivityManager.Stub implements 
Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 
@Override 
public final void attachApplication(IApplicationThread thread, long startSeq) { 
if (thread == null) { 
throw new SecurityException("Invalid application interface"); 
} 
synchronized (this) { 
int callingPid = Binder.getCallingPid(); 
final int callingUid = Binder.getCallingUid(); 
final long origId = Binder.clearCallingIdentity(); 
// 调用 attachApplicationLocked() 方法 
attachApplicationLocked(thread, callingPid, callingUid, startSeq); 
Binder.restoreCallingIdentity(origId); 
} } }

public ActivityTaskManagerInternal mAtmInternal; 

private boolean attachApplicationLocked(@NonNull IApplicationThread thread, 
int pid, int callingUid, long startSeq) { 
... ... 
// See if the top visible activity is waiting to run in this process... 
if (normalMode) { 
try { 
// 调用 attachApplication() 方法 
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController()); 
} catch (Exception e) { 
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); badApp = true; } } 
return true; }
public abstract class ActivityTaskManagerInternal { 
// 抽象方法,由 ActivityTaskManagerService 内部类 LocalService 实现 
public abstract boolean attachApplication(WindowProcessController wpc) throws 
RemoteException; }

public class ActivityTaskManagerService extends IActivityTaskManager.Stub { 
final class LocalService extends ActivityTaskManagerInternal { 
@Override 
public boolean attachApplication(WindowProcessController wpc) throws 
RemoteException { 
synchronized (mGlobalLockWithoutBoost) { 
// 调用 RootActivityContainer.attachApplication() 方法 
return mRootActivityContainer.attachApplication(wpc); 
} } } }
// 调用 ActivityStackSupervisor.realStartActivityLocked() 方法 
if (mStackSupervisor.realStartActivityLocked(activity, app, top == activity 
/* andResume */, true /* checkConfig */)) { 
didSomething = true; 
}

realStartActivityLocked 就是应用进程已经启动的情况下去启动 Activity 所调用的方法。

public class ActivityStackSupervisor implements RecentTasks.Callbacks { 
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController 
proc, boolean andResume, boolean checkConfig) throws RemoteException { 
... ... 
final TaskRecord task = r.getTaskRecord(); 
final ActivityStack stack = task.getStack(); 
beginDeferResume(); 
try { 
try { 
... ... 
// Create activity launch transaction. 
final ClientTransaction clientTransaction = ClientTransaction.obtain( 
proc.getThread(), r.appToken); 
final DisplayContent dc = r.getDisplay().mDisplayContent; 
// 为 ClientTransaction 对象添加 LaunchActivityItem 的 callback 
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, proc.getReportedProcState(), 
r.icicle, r.persistentState, results, newIntents, 
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(), 
r.assistToken)); 
// Set desired final state. 
final ActivityLifecycleItem lifecycleItem; // 设置当前的生命周期状态 
if (andResume) { 
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward()); } else { 
lifecycleItem = PauseActivityItem.obtain(); } 
clientTransaction.setLifecycleStateRequest(lifecycleItem); 
// 调用 ClientLifecycleManager.scheduleTransaction 方法 
mService.getLifecycleManager().scheduleTransaction(clientTransaction); 
... ... } catch (RemoteException e) { } } 
finally { endDeferResume(); } 
... ... 
return true; } }

执行 callback 后跳转到 LaunchActivityItem.execute()方法。

public class LaunchActivityItem extends ClientTransactionItem { 
@Override 
public void execute(ClientTransactionHandler client, IBinder token, 
PendingTransactionActions pendingActions) { 
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); 
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, 
mInfo, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, 
mPersistentState, mPendingResults, mPendingNewIntents, mIsForward, 
mProfilerInfo, client, mAssistToken); 
// 调用 ActivityThread.handleLaunchActivity() 方法 
client.handleLaunchActivity(r, pendingActions, null /* customIntent */); 
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); } }
public final class ActivityThread extends ClientTransactionHandler { 
@Override 
public Activity handleLaunchActivity(ActivityClientRecord r, 
PendingTransactionActions pendingActions, Intent customIntent) { 
// 调用 performLaunchActivity() 方法 
final Activity a = performLaunchActivity(r, customIntent); 
} }
public final class ActivityThread extends ClientTransactionHandler { 
/** Core implementation of activity launch. */ 
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); } 
// 初始化 ComponentName 
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 和 Activity 
ContextImpl appContext = createBaseContextForActivity(r); 
Activity activity = null; 
try { 
// 初始化 Application 
Application app = r.packageInfo.makeApplication(false, mInstrumentation); 
if (activity != null) { 
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); 
... ... 
r.lastNonConfigurationInstances = null; 
checkAndBlockForNetworkAccess(); 
activity.mStartedActivity = false; 
// 设置 Activity 的 Theme 
int theme = r.activityInfo.getThemeResource(); 
if (theme != 0) { activity.setTheme(theme); } 
activity.mCalled = false; 
if (r.isPersistable()) { 
// 调用 Instrumentation.callActivityOnCreate() 方法 
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); 
} else { 
mInstrumentation.callActivityOnCreate(activity, r.state); 
} 
r.activity = activity; } 
r.setState(ON_CREATE); 
synchronized (mResourcesManager) { 
mActivities.put(r.token, r); 
} } catch (SuperNotCalledException e) { ... ... } 
return activity; } }

流程小结:

image.png

public class Instrumentation { 
public void callActivityOnCreate(Activity activity, Bundle icicle) { 
prePerformCreate(activity); // 调用 performCreate() 方法 
activity.performCreate(icicle); 
postPerformCreate(activity); 
} }
public class Activity extends ContextThemeWrapper implements 
LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback, 
OnCreateContextMenuListener, ComponentCallbacks2, 
Window.OnWindowDismissedCallback, WindowControllerCallback, 
AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient { 
final void performCreate(Bundle icicle) { 
performCreate(icicle, null); } }

至此 executeCallbacks() 执行完毕,开始执行 executeLifecycleState() 方法,会先执行 cycleToPath() 方法(这边如果觉得乱的话,可以回去看下之前的分析)。

public class TransactionExecutor { 
private void cycleToPath(ActivityClientRecord r, int finish, boolean 
excludeLastState, ClientTransaction transaction) { 
final int start = r.getLifecycleState(); 
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState); 
// 调用 performLifecycleSequence() 方法 
performLifecycleSequence(r, path, transaction); 
} }

private ClientTransactionHandler mTransactionHandler; 
/** Transition the client through previously initialized state sequence. */ 
private void performLifecycleSequence(ActivityClientRecord r, IntArray path, 
ClientTransaction transaction) { 
final int size = path.size(); 
for (int i = 0, state; i < size; i++) { 
state = path.get(i); 
// 生命周期状态是从 ON_CREATE 状态到 ON_RESUME 状态,中间有一个 ON_START 状态, 
// 所以会执行 ActivityThread.handleStartActivity() 方法。 
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); } } }
public final class ActivityThread extends ClientTransactionHandler { 
@Override 
public void handleStartActivity(ActivityClientRecord r, PendingTransactionActions pendingActions) { 
final Activity activity = r.activity; 
... ...
// Start 
activity.performStart("handleStartActivity"); 
r.setState(ON_START); 
... ... } }
final void performStart(String reason) { 
... ... 
mInstrumentation.callActivityOnStart(this); 
... ... }
public class Instrumentation { public void callActivityOnStart(Activity activity) { 
// 最终调用了 Activity.onStart() 方法 activity.onStart(); } }

执行完毕 cycleToPath,开始执行 ResumeActivityItem.execute() 方法。

public class ResumeActivityItem extends ActivityLifecycleItem { 
@Override 
public void execute(ClientTransactionHandler client, IBinder token, 
PendingTransactionActions pendingActions) { 
// 调用 ActivityThread.handleResumeActivity() 方法 client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward, 
"RESUME_ACTIVITY"); 
} }
public final class ActivityThread extends ClientTransactionHandler { 
@Override 
public void handleResumeActivity(IBinder token, boolean finalStateRequest, 
boolean isForward, String reason) { 
// TODO Push resumeArgs into the activity for consideration final 
ActivityClientRecord r = performResumeActivity(token, finalStateRequest, 
reason); 
... ... 
// 这边的方法我们在最后会说明,其中涉及到 onStop() 方法 
Looper.myQueue().addIdleHandler(new Idler()); } }
public final class ActivityThread extends ClientTransactionHandler { 
public ActivityClientRecord performResumeActivity(IBinder token, boolean 
finalStateRequest, String reason) { 
... ... 
try { 
// 调用 performResume() 方法 
r.activity.performResume(r.startsNotResumed, reason); 
r.state = null; r.persistentState = null; r.setState(ON_RESUME); 
reportTopResumedActivityChanged(r, r.isTopResumedActivity, "topWhenResuming"); 
} catch (Exception e) { 
if (!mInstrumentation.onException(r.activity, e)) { 
throw new RuntimeException("Unable to resume activity " + 
r.intent.getComponent().toShortString() + ": " + e.toString(), e); } } 
return r; } }

final void performResume(boolean followedByPause, String reason) { 
dispatchActivityPreResumed(); 
performRestart(true /* start */, reason); 
... ... 
mInstrumentation.callActivityOnResume(this); 
... ... 
dispatchActivityPostResumed(); 
}
public class Instrumentation { 
public void callActivityOnResume(Activity activity) { 
activity.mResumed = true; 
// 调用了 Activity.onResume() 方法 
activity.onResume(); 
} }

至此,Activity 启动完毕。

流程小结:

image.png

我们在讨论 ActivityThread.handleResumeActivity() 源码的时候,最后一行代码比较特殊,还未进行讨论。

public final class ActivityThread extends ClientTransactionHandler { 
@Override 
public void handleResumeActivity(IBinder token, boolean finalStateRequest, 
boolean isForward, String reason) { 
// TODO Push resumeArgs into the activity for consideration final 
ActivityClientRecord r = performResumeActivity(token, finalStateRequest, 
reason); 
... ... 
// 当 MessageQueue 空闲的时候就会执行这个 Handler,即执行完当前 Activity 的 onResume() 方法后执行 
Looper.myQueue().addIdleHandler(new Idler()); 
} }

为什么要单独讨论这行代码?因为上面分析了栈顶 Activity 的 onPause()、新 Activity 的 onCreate()、onStart()、onResume(),但缺失一个栈顶 Activity 的 onStop() 生命周期,此方法就是在这行代码中处理的。

public final class ActivityThread extends ClientTransactionHandler { private 
class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities; 
boolean stopProfiling = false; 
if (mBoundApplication != null && mProfiler.profileFd != null && 
mProfiler.autoStopProfiler) { stopProfiling = true; } 
if (a != null) { 
mNewActivities = null; 
IActivityTaskManager am = ActivityTaskManager.getService(); 
ActivityClientRecord prev; 
do {
if (a.activity != null && !a.activity.mFinished) { 
try { 
// 调用 ActivityTaskManagerService.activityIdle() 方法 
am.activityIdle(a.token, a.createdConfig, stopProfiling); 
a.createdConfig = null; } catch (RemoteException ex) { 
throw ex.rethrowFromSystemServer(); } } 
prev = a; a = a.nextIdle; prev.nextIdle = null; } 
while (a != null); }
}
}
}
public class ActivityTaskManagerService extends IActivityTaskManager.Stub { 
ActivityStackSupervisor mStackSupervisor; 
@Override 
public final void activityIdle(IBinder token, Configuration config, boolean 
stopProfiling) { 
final long origId = Binder.clearCallingIdentity(); 
try { 
WindowProcessController proc = null; 
synchronized (mGlobalLock) { 
ActivityStack stack = ActivityRecord.getStackLocked(token); 
if (stack == null) { return; } 
// 调用 ActivityStackSupervisor.activityIdleInternalLocked 方法 
final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token, 
false /* fromTimeout */, false /* processPausingActivities */, config); 
if (r != null) { proc = r.app; } 
if (stopProfiling && proc != null) { proc.clearProfilerIfNeeded(); } } } 
finally { Binder.restoreCallingIdentity(origId); } } }
public class ActivityStackSupervisor implements RecentTasks.Callbacks { 
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean 
fromTimeout, boolean processPausingActivities, Configuration config) { 
... ... 
// Stop any activities that are scheduled to do so but have been 
// waiting for the next one to start. 
for (int i = 0; i < NS; i++) { 
r = stops.get(i); 
final ActivityStack stack = r.getActivityStack(); 
if (stack != null) { 
if (r.finishing) { 
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false, 
"activityIdleInternalLocked"); } else { 
// 调用 ActivityStack.stopActivityLocked() 方法 
stack.stopActivityLocked(r); 
} } } 
... ... 
return r; } }
final void stopActivityLocked(ActivityRecord r) { 
... ... 
if (r.attachedToProcess()) { 
adjustFocusedActivityStack(r, "stopActivity"); 
r.resumeKeyDispatchingLocked(); 
try { 
... ... 
EventLogTags.writeAmStopActivity( r.mUserId, System.identityHashCode(r), 
r.shortComponentName); 
// 又见面了 mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), 
r.appToken, StopActivityItem.obtain(r.visible, r.configChangeFlags)); 
if (shouldSleepOrShutDownActivities()) { r.setSleeping(true); } 
Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r); 
mHandler.sendMessageDelayed(msg, STOP_TIMEOUT); } catch (Exception e) { 
} } } }

又见到了 ClientLifecycleManager.scheduleTransaction() 方法,前面已经分析过多次,会去执行 StopActivityItem.execute() 方法,然后经过多次跳转,最终执行了 Activity.onStop() 方法。

public class StopActivityItem extends ActivityLifecycleItem { 
@Override 
public void execute(ClientTransactionHandler client, IBinder token, 
PendingTransactionActions pendingActions) { 
// 调用 ActivityThread.handleStopActivity() 方法 
client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions, 
true /* finalStateRequest */, "STOP_ACTIVITY_ITEM"); 
} }
public final class ActivityThread extends ClientTransactionHandler { 
@Override 
public void handleStopActivity(IBinder token, boolean show, int 
configChanges, PendingTransactionActions pendingActions, boolean 
finalStateRequest, String reason) { 
... ... 
performStopActivityInner(r, stopInfo, show, true /* saveState */, 
finalStateRequest, reason); 
... ... 
} }
public final class ActivityThread extends ClientTransactionHandler { 
private void performStopActivityInner(ActivityClientRecord r, StopInfo info, 
boolean keepShown, boolean saveState, boolean finalStateRequest, String 
reason) { 
if (r != null) { 
... ... 
if (!keepShown) { callActivityOnStop(r, saveState, reason); } } } }
public final class ActivityThread extends ClientTransactionHandler { 
private void callActivityOnStop(ActivityClientRecord r, boolean saveState, 
String reason) { 
final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state 
== null && !r.isPreHoneycomb(); 
final boolean isPreP = r.isPreP(); 
if (shouldSaveState && isPreP) { callActivityOnSaveInstanceState(r); } 
try { 
// 调用 Activity.performStop() 方法 
r.activity.performStop(r.mPreserveWindow, reason); 
} catch (SuperNotCalledException e) { throw e; } 
catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { throw new RuntimeException( "Unable to stop activity " + r.intent.getComponent().toShortString() + ": " + e.toString(), e); } } 
} } }
final void performStop(boolean preserveWindow, String reason) { 
... ... 
if (!mStopped) { 
dispatchActivityPreStopped(); 
if (mWindow != null) { mWindow.closeAllPanels(); } 
... ... 
mInstrumentation.callActivityOnStop(this); 
... ... 
mStopped = true; dispatchActivityPostStopped(); } 
mResumed = false; }
public class Instrumentation { public void callActivityOnStop(Activity activity) { activity.onStop(); } }

流程小结:

image.png

生命周期

Activity 的生命周期会直接受到 Activity 与其他 Activity、其任务及返回栈的关联性的影响。

一、正常情况的生命周期

用户感知到的、可理解的、操作后逻辑上一定会走的生命周期过程。如按back键退出,一定会走onPause、OnStop、OnDestroy。 onStart与onStop、onResume与onPause:从onPause状态回到前台会走到onResume状态,从onStop状态回到前台会到onStart状态。从是否可见来说,onStart和onStop是配对的;从是否在前台来说,onResume和onPause是配对的。 A启动B过程:A先走OnPause,然后B走OnCreate、OnStart、OnResume。(所以onPause中不能有重量级操作,否则影响B启动)

二、异常情况

一般正常情况的周期就像上面所说的一样,但是因为Android本身内存或者其他的一些情况会使得Activity不按照正常的生命周期。比如当资源配置发生改变、系统内存不足时,Activity就会可能被杀死。下面两种常见的情况:

资源相关的系统配置发生改变导致Activity被杀死并重新创建 如竖屏切换到横屏,由于系统配置发生了改变,在默认情况下,Activity就会被销毁并重新创建(当然我们也可以阻止系统重新创建,具体下面会说)。A销毁后立刻创建B,A中的一些信息会在B中恢复。

异常情况下的调用流程:

调用onSaveInstance保存当前Activity状态。注意,它与onPause方法没有先后之分。

调用onStop方法做后续处理。

调用onDestroy方法销毁当前活动。

重新onCreate该活动。

调用onStart方法之后,再调用onRestoreInstance方法加载保存的数据。

接下来就与正常的一样了,调用onResume,然后运行。

我们来看一下生命周期异常运行的系统日志:

03-23 00:19:23.480 26457-26457/com.example.david.lifecircle E/TAG: onCreate() is invoked!
03-23 00:19:23.481 26457-26457/com.example.david.lifecircle E/TAG: onStart() is invoked!
03-23 00:19:23.481 26457-26457/com.example.david.lifecircle E/TAG: onResume() is invoked!
03-23 00:19:51.323 26457-26457/com.example.david.lifecircle E/TAG: onPause() is invoked!
03-23 00:19:51.324 26457-26457/com.example.david.lifecircle E/TAG: onSaveInstanceState() is invoked!Save Text = Save Data
03-23 00:19:51.478 26457-26457/com.example.david.lifecircle E/TAG: onCreate() is invoked!
03-23 00:19:51.488 26457-26457/com.example.david.lifecircle E/TAG: onStart() is invoked!
03-23 00:19:51.490 26457-26457/com.example.david.lifecircle E/TAG: onRestoreInstanceState() is invoked!Recover Text = Save Data
03-23 00:19:51.490 26457-26457/com.example.david.lifecircle E/TAG: onResume() is invoked!

注意: onSaveInstanceState和onRestoreInstanceState调用时机:

当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。注意上面的双引号,何为“容易”?言下之意就是该activity还没有被销毁,而仅仅是一种可能性。这种可能性有哪些?有这么几种情况:

当用户按下HOME键时。

这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则

长按HOME键,选择运行其他的程序时。

按下电源按键(关闭屏幕显示)时。

从activity A中启动一个新的activity时。

屏幕方向切换时,例如从竖屏切换到横屏时。

在屏幕切换之前,系统会销毁activity A,在屏幕切换之后系统又会自动地创建activity A,所以onSaveInstanceState一定会被执行。

总而言之,onSaveInstanceState的调用遵循一个重要原则,即当系统“未经你许可”时销毁了你的activity,则onSaveInstanceState会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然你不保存那就随便你了)。

至于onRestoreInstanceState方法,需要注意的是,onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成对的被调用的,onRestoreInstanceState被调用的前提是,activity A“确实”被系统销毁了,而如果仅仅是停留在有这种可能性的情况下,则该方法不会被调用,例如,当正在显示activity A的时候,用户按下HOME键回到主界面,然后用户紧接着又返回到activity A,这种情况下activity A一般不会因为内存的原因被系统销毁,故activity A的onRestoreInstanceState方法不会被执行。

另外,onRestoreInstanceState的bundle参数也会传递到onCreate方法中,你也可以选择在onCreate方法中做数据还原。

2、资源内存不足导致低优先级的Activity被杀死 这种情况不好模拟,但是其数据存储和恢复过程和情况1完全一致,这里简单的描述一下Activity的优先级情况。Activity的优先级从高到低可以大致分为一下三种:

(1)前台Activity——正在和用户交互的Activity,优先级最高。

(2)可见但非前台Activity——比如Activity中弹出了一个对话框,导致Activity可见但无法和用户直接交互。

(3)后台Activity——已经被暂停或者停止的Activity,优先级最底。

当系统内存不足的时候,系统就会按照上述优先级从低到高来杀死目标Activity。并在后续通过onSaveInstance和onRestoreInstance来存储和恢复数据。 特别提醒的是:如果一个进程中没有四大组件(Activity、Service、ContentProvider、BroadCastReceiver)。那么这个进程就会很快被杀死,因此一些后台工作不适合脱离四大组件而独立运行在后台中,否则很容易被杀死。一般是将后台工作放入Service中从而保证进程有一定的优先级,这样才不会被系统轻易杀死。

补充:如何使得在系统配置放生改变后,Activity不被重新创建呢? 我们可以在AndroidMainfest.xml里,对< activity />增加一个android:configChanges属性,来指定在哪些配置改变的情况下Activity不需要重建。如下所示:

<code>android:configChanges="keyboardHidden|locale|screenSize|orientation"
//调出键盘、切换系统语言、屏幕尺寸(旋转屏幕时)改变、屏幕方向的改变时,不会重建Activi</code>

启动模式

launchMode

预备知识:任务栈(回退栈),后进先出

standard(标准模式):默认启动模式,每创建一个新Activity,都会产生一个新的Activity实例并且放入相应的任务栈中。和典型的栈调用数据类似没多大区别。比较常见的场景是:社交应用中,点击查看用户A信息->查看用户A粉丝->在粉丝中挑选查看用户B信息->查看用户A粉丝... 这种情况下一般我们需要保留用户操作 Activity 栈的页面所有执行顺序。

singleTop(栈顶复用模式):如果要新建的Activity本身已经有一个Activity实例位于栈顶时,那么这个Activity不会被重新创建,而是会回调onNewIntent方法取出当前请求的信息,而这个新建的Activity不会被系统调用onCreate、onStart方法。注意的是,该模式只使用于新Activity已经位于栈顶。否则的话还是会创建新的Activity并且进行压栈操作。例如:App 用户收到几条好友请求的推送消息,需要用户点击推送通知进入到请求者个人信息页,将信息页设置为 SingleTop 模式就可以增强复用性。

singTask(栈内复用模式):只要Activity在想要的任务栈中存在,会将栈内存在的Activity做置顶操作(由于“后进先出”,会clear top)。而如果在栈内不存在时,会直接创建并压栈。具体一点,想要的任务栈如果不存在,则创建一个任务栈然后创建实例入栈;如果想要的任务栈存在,则看是否存在实例,若存在则clearTop且onNewIntent,不存在则创建实例入栈。SingleTask 模式一般用作应用的首页,例如浏览器主页,用户可能从多个应用启动浏览器,但主界面仅仅启动一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。

singleInstance(单实例模式):加强的singleTask模式,除了具有singTask的一切特性外,还加强了一点,就是具有此模式的Activity只能单独的位于一个任务栈中。也就是说,在它启动的时候,系统会为它分配一个新的任务栈。由于singleTask的复用性,在其他需要创建Activity的时候,都不会创建新的Activity。如闹钟的提醒页面,当你在A应用中看视频时,闹钟响了,你点击闹钟提醒通知后进入提醒详情页面,然后点击返回就再次回到A的视频页面,这样就不会过多干扰到用户先前的操作了。

扩展:TaskAffinity(Activity想要的任务栈)

每个Activity都会有TaskAffinity参数,标识了Activity所需要进入的任务栈的名字。默认是包名,也就是当前应用下的任务栈。两种情况(其他情况没有意义): 当TaskAffinity和singleTask启动模式配对使用的时候:singleTask的activity会运行在TaskAffinity指定名字的任务栈中。 当TaskAffinity与allowTaskReparenting结合的时候:在这种情况下,如果该Activity的allowTaskReparenting设置为true的时候,这个Activity会直接进入后台,直到当和TaskAffinity名字相同的任务栈进入前台的时候,此时的Activity会转移到该任务栈中并处于栈顶位置。书中例子:先有应用A、B。当在A中启动B的一个ActivityC,然后按Home键回到桌面,打开B应用。此时你会发现显示出来的是ActivityC。 用法

<application android:allowTaskReparnting="true/false"></application>

是否允许activity更换从属的任务,比如从短信息任务 切换到浏览器任务。用来标记Activity能否从启动的Task移动到有着affinity的Task(当这个Task进入到前台时)——“true”,表示能移动,“false”,表示它必须呆在启动时呆在的那个Task里。

如果这个特性没有被设定,设定到元素上的allowTaskReparenting特性的值会应用到Activity上。默认值为“false”。

一般来说,当Activity启动后,它就与启动它的Task关联,并且在那里耗尽它的整个生命周期。当当前的Task不再显示时,你可以使用这个特性来强制Activity移动到有着affinity的Task中。典型用法是:把一个应用程序的Activity移到另一个应用程序的主Task中。

例如,如果e-mail中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序定义的,但是,现在它作为e-mail Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当e-mail Task再次进入前台时,就看不到它了。

Actvity的affinity是由taskAffinity特性定义的。Task的affinity是通过读取根Activity的affinity 决定。因此,根据定义,根Activity总是位于相同affinity的Task里。由于启动模式为“singleTask”和 “singleInstance”的Activity只能位于Task的底部,因此,重新宿主只能限于“standard”和“singleTop”模式。

注:在Intent中设置标志位来指定启动模式 比 通过AndroidMenifest.xml为Activity指定启动模式 优先级高。

FLAG_ACTIVITY_CLEAR_TOP

如果 TASK 中包含要启动的 Activity。那么将会移除掉它之上的所有 Activity。

Activity1 -> Activity2 -> Activity3(设置该启动标记启动到Activity1)

则 TASK 的 Activity 记录中只剩余 Activity1。

默认情况 B 会被销毁(finished)并重新创建;如果该 Intent 还设置了 FLAG_ACTIVITY_SINGLE_TOP 标记,或者 B 的启动模式(launch mode)被设置为非默认的模式(默认为 multiple),B 不会重新创建,而是接收到 onNewIntent()回调方法。

该标还可以跟 FLAG_ACTIVITY_NEW_TASK 合用。如果用来启动一个任务栈的根 Activity ,只要任何一个运行着的栈中有 Activity 的实例,系统就会将该任务带到前台,并且将此 Activity 顶上的 Activity 清除。这种方法在一些情况下非常在用,比如说当系统从通知栏启动一个 Activity 的时候。

FLAG_ACTIVITY_NEW_TASK

Activity1(设置该启动标记启动到Activity2) -> Activity2 -> Activity3 -> Activity1(设置该启动标记启动到Activity2) -> Activity2 -> Activity3

系统首先会查找有没有和 Activity2 的 Task affinity 相同的 Task 栈存在。

如果有存在,将 Activity2 压入那个栈。

则 TASK 的 Activity 记录中只剩余 Activity1,Activity2,Activity3,Activity1,Activity2,Activity3。

如果不存在则会新建一个 Activity2 的 affinity 的栈将其压入。

则 TASK 的 Activity 记录分为 TASK1:Activity1 TASK2:Activity2,Activity3,Activity1

此时 Activity1(设置该启动标记启动到Activity2) -> Activity2 并不会出发跳转页面,因为使用此标志时,如果任务已在正在启动的活动中运行,则不会启动新活动;相反,当前任务将简单地以最后一个状态显示在屏幕的前面。即显示 Activity1。

FLAG_ACTIVITY_NEW_TASK 常在启动器(launcher)中使用。当使用 FLAG_ACTIVITY_NEW_TASK 标记启动一个 Activity 时,系统会启动一个新的任务栈,这个栈可以被放到后台或推至前台,栈中的 Activity 顺序保持不变。当再次启动这个 Activity 时,系统不会创建一个新的任务栈,而是将已经运行着的任务栈推至前台,这个任务 栈会保持之前的状态(栈中的 Activity 列表、顺序及数据等)。

要取消这个问题可以同时设置 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK 来实现。

则 TASK 的 Activity 记录分为TASK1:Activity1。TASK2:Activity2,Activity3,Activity1,Activity2,Activity3。

使用一个新的Task来启动一个Activity,但启动的每个Activity都将在一个新的Task中。该Flag通常使用在从Service中启动Activity的场景,由于Service中并不存在Activity栈,所以使用该Flag来创建一个新的Activity栈,并创建新的Activity实例。

FLAG_ACTIVITY_MULTIPLE_TASK

该标记只有跟 FLAG_ACTIVITY_NEW_TASK 合用时才有效。

FLAG_ACTIVITY_NEW_TASK 与 FLAG_ACTIVITY_MULTIPLE_TASK 合用时 : 无论当前是否有一个任务栈已经运行,都会重新创建一个任务栈。因此除非你已经实现了一种方式使用户返回原来的任务,否则不要使用此标记。

FLAG_ACTIVITY_SINGLE_TOP

如果要启动的 Activity 就在栈顶,那么直接跳转到该 Activity,onNewIntent() 方法会被回调到。否则新建 Activity。

Activity1 -> Activity2 -> Activity3(设置该启动标记启动到Activity3)

则 TASK 的 Activity 记录中只剩余 Activity1,Activity2,Activity3。

FLAG_ACTIVITY_NO_HISTORY

该启动模式不会将跳转到的 Activity 加入到 TASK 中。

Activity1(设置该启动标记启动到Activity2) -> Activity2 -> Activity3

则 TASK 的 Activity 记录中只剩余 Activity1,Activity3。

FLAG_ACTIVITY_CLEAR_TASK

只有跟 FLAG_ACTIVITY_NEW_TASK 合用时有效。

使用该标记后,启动的的任务栈只有一个根 Activity 。

FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK

该启动模式可以将当前 TASK 的 Activity 全部清空。只剩待启动的 Activity。

Activity1 -> Activity2(设置该启动标记启动到Activity3) -> Activity3

则 TASK 的 Activity 记录中只剩余 Activity3。

FLAG_ACTIVITY_FORWARD_RESULT

Activity1 到达 Activity2 再到达 Activity3,但 Activity2 为过渡页可以finish了,此时 Activity3 将值透传至 Activity1。

Activity1(startActivityForResult) -> Activity2(设置该启动标记启动到Activity3,finish();) -> Activity3(setResult,finish();)

则 TASK 的 Activity 记录中只剩余 Activity1。

现在有个这样的需求,登录页是个选择登录页,里面含有帐号密码登录方式B、手机号登录/注册方式C、微信第三方登录D等几种选择,视为activity A。点击A中的某个button实现activity的跳转,比如B,在B中返回能跳到登录选择页。当B/C/D成功登录时,应跳转到主页面MainAcitivity E,此时点返回键应该是直接跳出应用,而不是又跳转会A/B/C/D页面去。单单是想让B/C/D页面消失,其实很容易,在做activity跳转时,finish当前页面即可。但页面A是没有办法清除的,解决方案如下:

Intent intent = new Intent(A.this,B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

FLAG_ACTIVITY_PREVIOUS_IS_TOP

使用该标记通常表明当前 Activity 将马上将被 finish 掉,它的上一个 Activity 作为栈顶,要启动的 Activity 将以上一个 Actiivty 来决定新创建还是调用栈顶 Activity 的 onNewIntent() 方法。

FLAG_ACTIVITY_REORDER_TO_FRONT

如果当前任务栈中有要启动的 Activity 的实例,这个标记会将此 Activity 放至栈顶。

Activity1 -> Activity2 -> Activity3 -> Activity4 (设置该启动标记启动到Activity2)

则 TASK 的 Activity 记录中只剩余 Activity1,Activity3,Activity4,Activity2。

当 Intent 中有 FLAG_ACTIVITY_CLEAR_TOP 标记时此标记被忽略。

FLAG_ACTIVITY_TASK_ON_HOME

只有与 FLAG_ACTIVITY_NEW_TASK 合用时有效。

把当前新启动的任务置于Home任务之上,当按back键从这个任务返回的时候会回到home,即使这个不是他们最后看见的activity。

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET

设置此标签相当于在任务栈中标记一个位置,当任务栈被重置时,从该标记位置到栈顶的 Activity 全部被清除。所谓的任务栈重置,是指当程序从后台进入前台时(通常是用户从主屏重新点击启动图标,或者从 recent apps 重新进入程序),如果栈顶的 Activity 设置了 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 标记,那么从设置 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 标记到栈顶的 Activity 会全部被清除掉。

举例:该标签可用于这种情况,用户在浏览邮件时,通过另外一个 Activity 来打开图片附件,这时用户可能会按 Home 键返回主屏,进行其它操作,一段时间后重新点击邮件的启动图标进入程序,这时应该显示邮件的内容而不是图片,因为用户可能是很长时间后返回邮件 App 的,也许已经忘记之前的操作,如果用户打开邮件后看到的是一张图片,可能会觉得很困惑。而设置 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 标记后,用户再次打开程序时,任务栈就会把图片 Activity 清除掉,显示邮件内容。

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

只有当新启动一个任务栈或任务栈被切换到前台时才有用,也就意味着该标记只会加在任务栈的根 Activity 上,用这个标记来表明需要重置任务栈的状态。

FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY

该标记通常不会在应用程序代码中设置,而是当系统从 “最近应用列表” 中启动 Activity 时添加。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

当在一个新任务中启动 Activity 时,此 Activity 会出现在最近应用程序 列表中(Android 2.3 及以前长按 Home 键,3.0及以后通过按多任务键)。如果设置此标记,该 Activity 就不会出现在最近程序列表中。

FLAG_ACTIVITY_NO_ANIMATION

当程序想从 A Activity 连续启动两个 Activity B 跟 C,可以使用此标记,系统会只显示 C 的过场动画,而不会连续出现多个 Activity 的过场动画。

FLAG_ACTIVITY_NO_USER_ACTION

onUserLeaveHint() 是 Activity 的一个生命周期方法,当用户操作使 Activity 进入后台时(如按下 Home 键等)会调用(时间早于 onPause() )。比如程序想要用户 “看到消息后取消通知”,就可以在该方法中得知用户已经 ”看到消息“ 了,此时可以取消通知(如闪烁的 LED 灯等)。

但在一些情况下,Activity 是系统自动启动的,比如来电界面。而使用 FLAG_ACTIVITY_NO_USER_ACTION 标记后,程序可以知道 Activity 的切换并不是用户操作的,而是系统自动启动的,onUserLeaveHint() 就不会被调用。

FLAG_ACTIVITY_BROUGHT_TO_FRONT

这个标记通常是系统使用的,当启动 lauchMode 为 SingleTask 的 Activity 时会设置该标记,应用程序中不常用。

IntentFilter匹配规则(隐式启动)

IntentFilter的过滤信息包括三种:action、category、data。一个Activity可以设定多个IntentFilter,只要有其中一组IntentFilter完全匹配,可以开启该Activity。

action的匹配规则

action的本质是一个字符串,其作用是描述Intent所触发的动作的名称。在IntentFilter中,我们可以定义多个action,只要有一个action和Intent传递的信息匹配,那么就算配合成功。注意的是,系统本身预定义了一些action,代表可启动的一些预定义的Activity,比如拨号界面等这些预定义的action集中放在android.intent.action下,调用的时候从里面选取,比如Intent.ACTION_CALL

category匹配规则

category和action的本质是一致的,但代表的意义不同,category描述的是目标组件的类别信息,表明这个目标可以干些什么。当然,我们也可以给它进行自定义的设置。而关于category的匹配规则,大致如下:如果Intent中含有category,那么不管你有几个,都需要和目标Activity在IntentFilter中设定的category匹配。

data的组成

data由两部分组成:mimeType 和URI。其中,mimeType指的媒体类型,可以表示图片image/jpeg,文本text/html ,音频audio/mpeg4-generic 和视频video/*等。而URI表示统一资源标识符(Uniform Resource Identifier),用以制定所需资源的存储路径。其结构如下: ://::/[||] 结构说明如下: scheme:URI的模式,比如http、file等 host:URI的主机名,即当前资源所在的主机的IP地址,可以用域名表示,如www.baidu.com port:URI的端口号,比如80,指获得资源的窗口路径。 path、pathPrefix、pathPattern:表示路径信息

data匹配规则与action类似。

补充:在隐式启动时,可以先判断是否有activity能匹配我们的隐式Intent,方法如下:

  Intent intent = new Intent();
    intent.setAction("com.hfy.test.action");
    intent.setDataAndType(Uri.parse("hfy://www.hfy.com"),"text/plain");
    intent.addCategory(CATEGORY_DEFAULT);
     
    ComponentName componentName = intent.resolveActivity(getPackageManager());
    if (componentName != null) {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }

application和activity两种context如何选择?

正确使用Context

一般Context造成的内存泄漏,几乎都是当Context销毁的时候,却因为被引用导致销毁失败,而Application的Context对象可以理解为随着进程存在的,所以我们总结出使用Context的正确姿势:

1:当Application的Context能搞定的情况下,并且生命周期长的对象,优先使用Application的 Context。

2:不要让生命周期长于Activity的对象持有到Activity的引用。

3:尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,如果使用静态内部类,将外部实例引用作为弱引用持有。