Android 10 Activity 创建流程
ActivityThread作为主应用程序的主线程管理类,我们都从main方法开始分析。main方法主要功能是创建ActivityThread且关联,创建Looper死循环不让程序退出。
public static void main(String[] args) {
...
//为主线程创建loop对象,我们在主线程使用Handler时候没有初始化都可以使用,因为这里做了初始化。
Looper.prepareMainLooper();
...
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
//开始死循环获得消息
Looper.loop();
}
接下来我们分析一下ActivityThread的attach方法,在调用attach时候第一个参数传递的是false,我们可以看出它通过AMS跨进程调用了attachApplication方法。
private void attach(boolean system, long startSeq) {
if (!system) {
...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
...
}
接下来我们需要去framework看AMS源码才能只知道里面到底做了什么事情,
最后调用了attachApplicationLocked方法,然后回调到主进程ApplicationThread的bindApplication方法里面去。
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
...
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
...
}
我们继续分析主进程ActivityThread,AMS通知它创建Application,且两个进程之间数据同步。
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, AutofillOptions autofillOptions,
ContentCaptureOptions contentCaptureOptions) {
...
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableBinderTracking = enableBinderTracking;
data.trackAllocation = trackAllocation;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
data.buildSerial = buildSerial;
data.autofillOptions = autofillOptions;
data.contentCaptureOptions = contentCaptureOptions;
sendMessage(H.BIND_APPLICATION, data);//1
}
我们从上面代码看出第一点,在ApplicationThread通过H类是继承Handler,通过发送消息到主线程管理类ActivityThread执行绑定Application,调用handleBindApplication方法。创建LoadedApk对象并且用于创建Application。
private void handleBindApplication(AppBindData data) {
//设置进程名字
Process.setArgV0(data.processName);
//创建LoadedApk实例
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
app = data.info.makeApplication(data.restrictedBackupMode, null);
}
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
//1
if (mApplication != null) {
return mApplication;
}
Application app = null;
try {
ClassLoader cl = getClassLoader();
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//2
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
}
mApplication = app;
if (instrumentation != null) {
//3
instrumentation.callApplicationOnCreate(app);
}
return app;
}
从上述代码我们可以看出,
1:如果有已经创建好了Applicaiton对象及返回。
2:创建Application对象,并且与appContext建立关联关系,且调用attach方法
3:通过instrumentation调用执行onCreate方法
然后我们在回到AMS代码里面及方法attachApplicationLocked,看看是如何执行跳转Activity的。
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
return mRootActivityContainer.attachApplication(wpc);
}
我们可以看出下面代码realStartActivityLocked,这个都是我们真正发起创建Activity的方法,然后我们继续分析代码。
//frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {
final String processName = app.mName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
final ActivityStack stack = display.getFocusedStack();
if (stack != null) {
stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
final ActivityRecord top = stack.topRunningActivityLocked();
final int size = mTmpActivityList.size();
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
//执行跳转
if (mStackSupervisor.realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
} catch (RemoteException e) {
}
}
}
}
}
return didSomething;
}
在下面的代码主要作用是,发送指令到应用进程创建Activity,LaunchActivityItem表示一个创建任务。
//frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
//启动指令
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);
// Schedule transaction. 跨进程调用到应用进程
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
return true;
}
于是开始执行命令到,
//ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
//ClientTransaction.java
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
上述代码mClient实际都是ApplicationThread,那我们由此知道,马上都会创建真正的Activity了,接下来我们继续分析,我们来到ApplicationThread这个类里面的这个scheduleTransaction方法。
//ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
上述代码看出,最终代买执行到了ActivityThread,然后通过发送消息到主线程管理执行创建Activity,ActivityThread继承了ClientTransactionHandler。
//TransactionExecutor.java
public void execute(ClientTransaction transaction) {
executeCallbacks(transaction);
//之前执行暂停调用这个方法
executeLifecycleState(transaction);
}
public void executeCallbacks(ClientTransaction transaction) {
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
}
}
经过上述代码的表演,我们来到了LaunchActivityItem这个类。
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
//与 ActivityRecord 信息同步 token信息通讯
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client, mAssistToken);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
走到这里我们开始创建ActivityClientRecord来记录Activity的信息,并且通过token与AMS的ActivityRecord相应关联。继续看handleLaunchActivity的源码,如下。
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
final Activity a = performLaunchActivity(r, customIntent);
return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
} catch (Exception e) {
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
appContext.setOuterContext(activity);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.activity = activity;
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
}
return activity;
}
相关文章
- 金融服务领域的大数据:即时分析
- 影响大数据、机器学习和人工智能未来发展的8个因素
- 从0开始构建一个属于你自己的PHP框架
- 如何将Hadoop集成到工作流程中?这6个优秀实践必看
- SEO公司使用大数据优化其模型的5种方法
- 关于Web Workers你需要了解的七件事
- 深入理解HTTPS原理、过程与实践
- 增强分析:数据和分析的未来
- PHP协程实现过程详解
- AI专家:大数据知识图谱——实战经验总结
- 关于PHP的错误机制总结
- 利用数据分析量化协同过滤算法的两大常见难题
- 怎么做大数据工作流调度系统?大厂架构师一语点破!
- 2019大数据处理必备的十大工具,从Linux到架构师必修
- OpenCV中的KMeans算法介绍与应用
- 教大家如果搭建一套phpstorm+wamp+xdebug调试PHP的环境
- CentOS下三种PHP拓展安装方法
- Go语言HTTP Server源码分析
- Go语言HTTP Server源码分析
- 2017年4月编程语言排行榜:Hack首次进入前五十