启动流程
一、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() 方法。
流程小结:
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); } } }
流程小结:
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();
} }
流程小结:
在启动一个 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() 方法来为应用创建进程。
源码最后会执行到 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; } }
流程小结:
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 启动完毕。
流程小结:
我们在讨论 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(); } }
流程小结:
生命周期
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中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,如果使用静态内部类,将外部实例引用作为弱引用持有。