前言
从第一天接触Android开发开始,大家都知道Activity是Android中最最最重要的一个组件。既然很重要,很多在Android开发岗位工作几年了,都对Activity讲不出个所以然出来。比如:
1.Activity的创建
2.Activity生命周期函数的调用
既然这么重要,这么多问题困扰小伙伴们,希望通过本章的学习,帮助小伙伴们对Activity有个全新的认识。
众所周知,java程序想要开启需要依赖于main方法,也就是程序入口(主线程)进入。熟悉的小伙伴可能都知道在Android当中存在一个叫做ActivityThread的类,这个类代表的是Android当中的主线程,而在这个类当中会有一个比较熟悉的main方法,Android在打开app时首先调用的是ActivityThread的main方法,这也就是一个app进程的启动点。
##ActivityThread
public static void main(String[] args) {
...
Looper.prepareMainLooper();
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
ActivityThread thread = new ActivityThread(); //1
thread.attach(false, startSeq); //2
...
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
在main方法的注释1处,创建了ActivityThread,接着在注释2处,调用了attach方法,意为连接,具体连接什么,我们接着往下分析。
##ActivityThread
private void attach(boolean system, long startSeq) {
...
if (!system) {
...
final IActivityManager mgr = ActivityManager.getService(); //1
try {
mgr.attachApplication(mAppThread, startSeq); //2
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
...
}
...
}
attach方法,在注释1处,通过AIDL,得到AMS的本地代理对象IActivityManager ,作用应用进程请求系统进程的接口,实现跟AMS服务跨进程间通信。这里设计到AIDL的用法,和AMS相关的基础知识,这部分内容不在本章节探讨。接着看注释2,使用IActivityManager 对象调用了attachApplication方法,主要是为了连接Application。Application这个类小伙伴们肯定是不陌生的,一般会在这个类中去初始化一些需要在Activity启动之前初始化的资源,或是配置一些整个应用需要用到的东西,让真个App(任何类中)都能访问到。那么这里跟AMS进行连接,主要让当前App跟Android系统绑定起来,方便系统管理当前App。
##ActivityManagerService
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
//获取pid
int callingPid = Binder.getCallingPid(); //1
//获取uid
final int callingUid = Binder.getCallingUid(); //2
final long origId = Binder.clearCallingIdentity();
//连接Application
attachApplicationLocked(thread, callingPid, callingUid, startSeq); //3
Binder.restoreCallingIdentity(origId);
}
}
attachApplication是AMS中的一个方法,注释1和2分别获取到pid和uid(由系统创建,并分配,并且是处以没有进程使用)。这里小伙伴们可以猜想一下,获取到pid和uid肯定是把它分配到当前进程。在注释3,可以看到pid和uid传入到了attachApplicationLocked这个方法中。
##ActivityManagerService
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
ProcessRecord app; //1
long startTime = SystemClock.uptimeMillis();
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid); //2
}
}
...
if (app.instr != null) { //当前进程是否正在活动
thread.bindApplication(processName, appInfo, providers, app.instr.mClass,
profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection,
testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()),
app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled); //3
} else {
//Application 绑定到当前线程
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode, mBinderTransactionTrackingEnabled,
enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); //4
}
...
//检测最可见的Activity是否在运行进程中等待,如果再则创建Activity
if (mStackSupervisor.attachApplicationLocked(app)) { //5
didSomething = true;
}
...
}
attachApplicationLocked方法中,注释1处的ProcessRecord是个进程记录类,小伙伴们可以把这个类理解成为一个javabean,用来保存当前进程先关的一些信息(如pid、uip、ApplicationInfo等),在注释2中,根据pid获取到了这个类。注释3和注释4都是为了绑定Application,调用的是IApplicationThread 中的bindApplication方法,而IApplicationThread 它是一个AIDL接口,作用是系统进程请求应用进程的接口。而它的实现类是在ActivityThread中的一个内部类ApplicationTread继承了IApplicationThread.Stub。注释5是开始创建Activity。这里我们分开来探讨绑定Application和创建Activity。
绑定Application
##ActivityThread.ApplicationThread
public final void bindApplication(String processName...boolean autofillCompatibilityEnabled) {
...
setCoreSettings(coreSettings);
AppBindData data = new AppBindData();
data.processName = processName; //当前进程名字
data.appInfo = appInfo; //app信息
data.providers = providers; //providers
...
//最后使用Handler发送消息,并携带AppBindData数据
sendMessage(H.BIND_APPLICATION, data);
}
在ActivityThread.ApplicationTread类中,bindApplication方法携带了一系列参数,把这些数据封装成了一个AppBindData 对象,最后使用Handler发送消息,并携带AppBindData数据。H是ActivityThread中的内部类,是Handler的子类。
##ActivityThread.H
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData) msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
...
}
handleMessage方法是H中的方法,主要是用来处理消息。
##ActivityThread
private void handleBindApplication(AppBindData data) {
...
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); //1
...
Application app;
...
//创建Application
app = data.info.makeApplication(data.restrictedBackupMode, null); //2
...
//调用Application中的onCreate方法
mInstrumentation.callApplicationOnCreate(app); //3
...
}
##Instrumentation
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
handleBindApplication方法中,注释1,获取Application的上下文,也就是getApplicationContext()获取到的ContextImpl ,ContextImpl 是Context的子类。注释2,通过类加载器,和反射创建出Application。注释3,接着可以看到Application的onCreate方法的调用。
小结,链接Application,可以理解为三个步骤,第一个步骤获取pid和uid,第二步通过IApplicationThread请求当前应用进程,第三步创建Application。
创建Activity
##ActivityStackSupervisor
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
...
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
...
}
经过一系列的检测或判断后,会realStartActivityLocked方法,真正的开始Activity的解锁(创建)。
##ActivityStackSupervisor
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
...
// 创建启动Activity
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo)); //添加LaunchActivityItem的回调
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// 通过生命周期管理对象ClientLifecycleManager,来管理Activity的生命周期状态
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
return true;
}
此处,添加LaunchActivityItem。再后续的真正开始创建Activity时会用到。
##ClientLifecycleManager
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
//ClientTransaction是个javabean 实现了Parcelable 序列化。
//schedule()方法内部,会回调到ActivityThread.ApplicationThread的scheduleTransaction()方法
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
接着会走到
##ActivityThread.ApplicationTread
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
//ActivityThread.this 指的是父类ClientTransactionHandler
ActivityThread.this.scheduleTransaction(transaction);
}
##ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
//发送Handler消息
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
在handleMessage方法中处理的EXECUTE_TRANSACTION这条消息。
##ActivityThread.H
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;
//开始执行
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
...
}
...
}
接着看execute方法。
##TransactionExecutor
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction); //1
executeLifecycleState(transaction); //5
mPendingActions.clear();
log("End resolving transaction");
}
##TransactionExecutor
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks(); //2
...
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i); //3
...
item.execute(mTransactionHandler, token, mPendingActions); //4
...
}
}
executeCallbacks方法,注释1执行回调。注释2获取到ClientTransaction中的ClientTransactionItem集合。注释3处理回调,这里获取到的ClientTransactionItem是LaunchActivityItem。注释4调用LaunchActivityItem中的execute方法。注释5是执行生命周期状态的改变,这里没有给小伙伴们贴出代码,感兴趣的小伙伴去看看。举个例子,比如Activity首次创建,默认的生命周期状态是ON_CREATE,再进行完onCreate方法调用结束后,生命周期状态值会往后移,也就是状态改变成ON_START,onStart方法调用结束,状态改变成ON_RESUME。
##LaunchActivityItem
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
...
client.handleLaunchActivity(r, pendingActions, null /* customIntent */); //1
...
}
execute方法中,ClientTransactionHandler是个抽象类,他的子类是ActivityThread。接着调用到的是
ActivityThread中的handleLaunchActivity方法。
##ActivityThread
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
//开始执行
final Activity a = performLaunchActivity(r, customIntent); //1
...
return a;
}
注释1,开始执行启动Activity的创建。
##ActivityThread
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo; //1
...
ContextImpl appContext = createBaseContextForActivity(r); //2
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader(); //3
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); //4
...
} catch (Exception e) {
...
}
...
//调用Activity的OnCreate()方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); //5
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
return activity;
}
performLaunchActivity方法中,注释1获取Activity信息。 注释2获取Activity 上下文。注释3获取到ClassLoader 类加载器对象。注释4使用ClassLoader(类加载器)加载出Activity,再使用反射new出Activity。注释5调用Activity的onCreate方法。
##Instrumentation
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle); //1
postPerformCreate(activity);
}
注释1处,调用Activity中performCreate方法
##Activity
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
##Activity
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
mCanEnterPictureInPicture = true;
restoreHasCurrentPermissionRequest(icicle);
//onCreate 生命周期方法被调用
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
performCreate方法中会调用onCreate方法。到这里Activity的创建已经结束啦。
备注:文中Android源码版本9.0
作者:Alan
原创博客,请注明转载处....