(Android11.0)App启动过程的深度挖掘(下篇)
Posted 丶笑看退场
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(Android11.0)App启动过程的深度挖掘(下篇)相关的知识,希望对你有一定的参考价值。
前文说到,Activity启动过程在ATMS
中绕了一大圈,最终还是通过调用ClientTransaction
的schedule
方法,回到了ApplicationThread
中。那我们就接着往下看启动过程。
ActivityThread启动Activity
我们来看下ApplicadtionThread
的scheduleTransaction
方法:
### ActivityThread/ApplicationThread
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException
ActivityThread.this.scheduleTransaction(transaction);
实际上最终实现调用的是在ActivityThread
的父类ClientTransactionHandler
中:
### ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction)
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
方法很简单,就是发送一个启动消息交由Handler处理,这个handler有着一个很简单的名字:H。在这里地调用了sendMessage
方法向H类发送类型为EXECUTE_TRANSACTION
消息,sendMessage方法如下所示:
### ActivityThread
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async)
if (DEBUG_MESSAGES)
Slog.v(TAG,
"SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async)
msg.setAsynchronous(true);
mH.sendMessage(msg);
这里mH指的是H,它是ActivityThread的内部类并继承Handler,是应用程序进程中主线程的消息管理类
。
再想下这个消息是从哪里发送出来的? 我们知道,服务器的Binder方法运行在Binder的线程池中,也就是说系统进行跨进程调用ApplicationThread的scheduleTransaction就是执行在Binder的线程池中的了。
接着来看下Handler H对消息的处理,如下所示:
### ActivityThread
final H mH = new H();
class H extends Handler
public static final int BIND_APPLICATION = 110;
......
public static final int EXECUTE_TRANSACTION = 159;
public static final int RELAUNCH_ACTIVITY = 160;
......
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;
case EXIT_APPLICATION:
if (mInitialApplication != null)
mInitialApplication.onTerminate();
Looper.myLooper().quit();
break;
.......
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem())
//系统进程内的客户端事务在客户端而不是 ClientLifecycleManager 被回收,以避免在处理此消息之前被清除。
transaction.recycle();
// 回收本地预定的事务。
break;
case RELAUNCH_ACTIVITY:
handleRelaunchActivityLocally((IBinder) msg.obj);
break;
.......
.......
查看H的handleMessage
方法中对EXECUTE_TRANSACTION
的处理。取出ClentTransaction
实例,调用execute
方法。
### TransactionExector
public void execute(ClientTransaction transaction)
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
final IBinder token = transaction.getActivityToken();
......
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
接着来看executeCallbacks
方法:
### TransactionExector
public void executeCallbacks(ClientTransaction transaction)
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
......
final int size = callbacks.size();
for (int i = 0; i < size; ++i)
final ClientTransactionItem item = callbacks.get(i);
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
final int postExecutionState = item.getPostExecutionState();
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());
if (closestPreExecutionState != UNDEFINED)
cycleToPath(r, closestPreExecutionState, transaction);
//关键代码
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
if (r == null)
// Launch activity request will create an activity record.
r = mTransactionHandler.getActivityClient(token);
......
可以看到遍历了Callbacks
,调用了execute
方法。那这里的item
又是什么?
### ActivityStackSupervisor.realStartActivityLocked
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
从上篇文章知道,放入callbacks里的其实是ClientTransactionItem
的子类LaunchActivityItem
,所以我们关注下launchActivityItem
中的execute
方法。
### launchActivityItem
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, mFixedRotationAdjustments);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
这里ClientTransactionHandler
是ActivityThread
的父类。又将启动Activity的参数封装成ActivityClientRecord,最后调用了handleLaunchActivity
方法。
Activity启动核心实现
下面开始启动过程代码基本android
7.0
,8.0
,9.0
,10.0
一样
### ActivityThread
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent)
......
// 在创建活动之前初始化
if (!ThreadedRenderer.sRendererDisabled
&& (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0)
HardwareRenderer.preload();
WindowManagerGlobal.initialize();
GraphicsEnvironment.hintActivityLaunch();
//启动Activity
final Activity a = performLaunchActivity(r, customIntent);
if (a != null)
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
if (!r.activity.mFinished && pendingActions != null)
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
pendingActions.setCallOnPostCreate(true);
else
try
//停止Activity启动
ActivityTaskManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
catch (RemoteException ex)
throw ex.rethrowFromSystemServer();
return a;
performLaunchActivity
方法最终完成了Activity
对象的创建和启动过程。我们再来看下performActivity
方法做了什么。
### ActivityThread
//核心实现
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent)
//从ActivityClientRecord中后去待启动的Activity的组件信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null)
//获取APK文件的描述类LoadedApk
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
//ComponentName类中保存了该Activity的包名和类名
ComponentName component = r.intent.getComponent();
......
//创建要启动Activity的上下文环境
//Context中的大部分逻辑都是由ContextImpl来完成
ContextImpl appContext = createBaseContextForActivity(r);
//通过Instrumentation的newActivity方法使用类加载创建Activity对象。
Activity activity = null;
try
java.lang.ClassLoader cl = appContext.getClassLoader();
//根据ComponentName中存储的Activity类名,用类加载器来创建该Activity的实例
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null)
r.state.setClassLoader(cl);
catch (Exception e)
if (!mInstrumentation.onException(activity, e))
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
try
//创建Application,makeApplication方法内部会调用Application的onCreate方法
Application app = r.packageInfo.makeApplication(false, mInstrumentation); //注释1
.......
if (activity != null)
.......
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow)
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
// 必须使用与应用程序上下文相同的加载器来初始化活动资源。
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(activity);
// 初始化Activity
//attach方法中会创建Window对象(PhoneWindow)并与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 (customIntent != null)
activity.mIntent = customIntent;
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
.......
activity.mCalled = false;
if (r.isPersistable())
//调用Instrumentation的callActivityOnCreate方法来启动Activity
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); //注释2
else
mInstrumentation.callActivityOnCreate(activity, r.state);
.......
r.activity = activity;
mLastReportedWindowingMode.put(activity.getActivityToken(),
config.windowConfiguration.getWindowingMode());
r.setState(ON_CREATE);
synchronized (mResourcesManager)
mActivities.put(r.token, r);
catch (SuperNotCalledException e)
throw e;
........
return activity;
再来看下注释1 处,Application是怎么被创建出来的? makeApplication
方法,如下所示:
### LoadApk
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation)
if (mApplication != null)
return mApplication;
.......
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null))
appClass = "android.app.Application";
.......
try
final java.lang.ClassLoader以上是关于(Android11.0)App启动过程的深度挖掘(下篇)的主要内容,如果未能解决你的问题,请参考以下文章
(Android11.0)Android启动过程的深度挖掘(上篇)
阿里大佬首次分享《Android11.0最新Framework解析》限时免费下载高清PDF文档