APP启动流程
创建Application
首先每个APP都有一个main方法的入口,在Android中main方法是在ActivityThread中的。
ActivityThread#main
public static void main(String[] args) {
//代码省略
}
紧接着在main方法中实例化了ActivityThread
public static void main(String[] args) {
//代码省略
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
//代码省略
}
在attach方法中会通过ActivityManagerService实例化Application
ActivityThread#attach
private void attach(boolean system, long startSeq) {
//代码省略
//得到ActivityManagerService
final IActivityManager mgr = ActivityManager.getService();
try {
//重点在这句
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
//代码省略
}
ActivityManagerService#attachApplication
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
//重点代码
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
ActivityManagerService#attachApplicationLocked
@GuardedBy("this")
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
//代码省略
if (app.isolatedEntryPoint != null) {
// This is an isolated process which should just call an entry point instead of
// being bound to an application.
thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
} else if (instr2 != null) {
//重点代码,其中的thread就是ActivityThread
thread.bindApplication(processName, appInfo, providers,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
} else {
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);
}
//代码省略
}
可以看到thread.bindApplication,这里的thread其实就是ActivityThread。
ActivityThread#bindApplication
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) {
//代码省略
sendMessage(H.BIND_APPLICATION, data);
}
发送了一个消息到ActivityThread内部的一个handle里。找到handle,其中会调用handleBindApplication(data);
ActivityThread#handleBindApplication(data);
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
//代码省略
//data.info得到的是一个LoadedApk对象
app = data.info.makeApplication(data.restrictedBackupMode, null);
//代码省略
}
LoadedApk#makeApplication
@UnsupportedAppUsage
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
//如果已经实例化过了,就不会再实例化了,返回之前的application对象
if (mApplication != null) {
return mApplication;
}
//代码省略
//mActivityThread.mInstrumentation返回的是Instrumentation
//实例化application对象
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
//代码省略
}
Instrumentation#newApplication。
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
//通过反射实例化application对象
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
app.attach(context);
return app;
}
再回到ActivityThread#handleBindApplication
ActivityThread#handleBindApplication
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
//代码省略
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
//调用了application的onCreate方法
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
//代码省略
}
到此Application的创建就完成了,接下来就是Activity的创建
创建Activity
回到ActivityManagerService#attachApplicationLocked
ActivityManagerService#attachApplicationLocked
@GuardedBy("this")
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
//代码省略
if (normalMode) {
try {
//mStackSupervisor其实是ActivityStackSupervisor,调用activity堆栈方法
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
//代码省略
}
ActivityStackSupervisor#attachApplicationLocked
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
//代码省略
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
//代码省略
}
ActivityStackSupervisor#realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
//代码省略
// Create activity launch transaction.
//创建启动activity事务
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
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, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
//代码省略
// Schedule transaction.
//通过ClientLifecycleManager提交事务
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
//代码省略
}
ClientLifecycleManager#scheduleTransaction
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
//还是调用ClientTransaction#schedule
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();
}
}
ClientTransaction#schedule
public void schedule() throws RemoteException {
//这里实际是调用了ApplicationThread的scheduleTransaction
mClient.scheduleTransaction(this);
}
ApplicationThread#scheduleTransaction
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
//调用ActivityThread父类的scheduleTransaction方法
ActivityThread.this.scheduleTransaction(transaction);
}
ClientTransactionHandler#scheduleTransaction
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
//发送消息到ActivityThread内的handle中
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
ActivityThread#H
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
//调用了TransactionExecutor的execute
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;
TransactionExecutor#execute
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
//获取ClientTransaction里面的Callbacks
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
/** Cycle through all states requested by callbacks and execute them at proper times. */
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
//代码省略
//最开始在ActivityStackSupervisor#realStartActivityLocked中,实例化ClientTransaction时,addCallback传入的是LaunchActivityItem, //所以这里执行的其实是LaunchActivityItem#execute
item.execute(mTransactionHandler, token, mPendingActions);
//代码省略
}
LaunchActivityItem#execute
@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);
//ClientTransactionHandler是ActivityThread的父类,所以这里的client其实就是ActivityThread
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
ActivityThread#handleLaunchActivity
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
//代码省略
//执行启动activity
final Activity a = performLaunchActivity(r, customIntent);
//代码省略
}
ActivityThread#performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//代码省略
//创建Activity实例
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
//代码省略
//调用Activity#OnCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
//代码省略
}
到此Activity就启动完成了。下图是一个别人做的一个流程图,十分简单明了。
**App启动流程**加载XML布局
Activity
Activity#setContentView
public void setContentView(@LayoutRes int layoutResID) {
//getWindow()获取到的是PhoneWindow
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
PhoneWindow#setContentView
@Override
public void setContentView(int layoutResID) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
if (mContentParent == null) {
//安装装饰
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
PhoneWindow#installDecor
private void installDecor() {
//代码省略
if (mDecor == null) {
//初始化DecorView
mDecor = generateDecor(-1);
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
}
} else {
mDecor.setWindow(this);
}
if (mContentParent == null) {
//初始化ContentView,也就是用来承载我们自己布局的父控件
mContentParent = generateLayout(mDecor);
//代码省略
}
}
PhoneWindow#generateDecor
protected DecorView generateDecor(int featureId) {
// System process doesn't have application context and in that case we need to directly use
// the context we have. Otherwise we want the application context, so we don't cling to the
// activity.
Context context;
if (mUseDecorContext) {
Context applicationContext = getContext().getApplicationContext();
if (applicationContext == null) {
context = getContext();
} else {
context = new DecorContext(applicationContext, getContext());
if (mTheme != -1) {
context.setTheme(mTheme);
}
}
} else {
context = getContext();
}
return new DecorView(context, featureId, this, getAttributes());
}
PhoneWindow#generateLayout
protected ViewGroup generateLayout(DecorView decor) {
//代码省略
//根据主题等定义了xml布局id之后,加载布局
mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
//代码省略
}
DecorView#onResourcesLoaded
void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
//代码省略
//通过inflater来加载布局
final View root = inflater.inflate(layoutResource, null);
if (mDecorCaptionView != null) {
if (mDecorCaptionView.getParent() == null) {
addView(mDecorCaptionView,
new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
mDecorCaptionView.addView(root,
new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT));
} else {
// Put it below the color views.
addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
mContentRoot = (ViewGroup) root;
//代码省略
}
加载完成DecorView与ContentParentView之后,再回到setContentView方法,加载我们自己的xml布局
PhoneWindow#setContentView
@Override
public void setContentView(int layoutResID) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
//判断主题加载我们自己的xml布局
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
//通过LayoutInflater加载我们自己的xml布局
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
PhoneWindow#transitionTo
private void transitionTo(Scene scene) {
if (mContentScene == null) {
scene.enter();
} else {
mTransitionManager.transitionTo(scene);
}
mContentScene = scene;
}
Scene#enter
public void enter() {
// Apply layout change, if any
if (mLayoutId > 0 || mLayout != null) {
// empty out parent container before adding to it
getSceneRoot().removeAllViews();
if (mLayoutId > 0) {
//通过LayoutInflater加载我们自己的xml布局
LayoutInflater.from(mContext).inflate(mLayoutId, mSceneRoot);
} else {
mSceneRoot.addView(mLayout);
}
}
// Notify next scene that it is entering. Subclasses may override to configure scene.
if (mEnterAction != null) {
mEnterAction.run();
}
setCurrentScene(mSceneRoot, this);
}
AppCompatActivity
AppCompatActivity#setContentView
@Override
public void setContentView(@LayoutRes int layoutResID) {
//getDelegate()获取到的是AppCompatDelegate,他的实现类是AppCompatDelegateImpl
getDelegate().setContentView(layoutResID);
}
AppCompatDelegateImpl.setContentView
@Override
public void setContentView(int resId) {
ensureSubDecor();
ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
LayoutInflater.from(mContext).inflate(resId, contentParent);
mAppCompatWindowCallback.getWrapped().onContentChanged();
}
AppCompatDelegateImpl.ensureSubDecor
private void ensureSubDecor() {
if (!mSubDecorInstalled) {
//初始化mSubDecor
mSubDecor = createSubDecor();
//代码省略
}
}
AppCompatDelegateImpl.createSubDecor
private ViewGroup createSubDecor() {
//代码省略
//在获取DecorView的时候就会进行DecorView的初始化,调用PhoneWindow的installDecor方法。
mWindow.getDecorView();
final LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup subDecor = null;
根据主题初始化subDecor
//代码省略
final ContentFrameLayout contentView = (ContentFrameLayout) subDecor.findViewById(
R.id.action_bar_activity_content);
final ViewGroup windowContentView = (ViewGroup) mWindow.findViewById(android.R.id.content);
if (windowContentView != null) {
// There might be Views already added to the Window's content view so we need to
// migrate them to our content view
while (windowContentView.getChildCount() > 0) {
final View child = windowContentView.getChildAt(0);
windowContentView.removeViewAt(0);
contentView.addView(child);
}
// Change our content FrameLayout to use the android.R.id.content id.
// Useful for fragments.
//修改原有布局id
windowContentView.setId(View.NO_ID);
contentView.setId(android.R.id.content);
// The decorContent may have a foreground drawable set (windowContentOverlay).
// Remove this as we handle it ourselves
if (windowContentView instanceof FrameLayout) {
((FrameLayout) windowContentView).setForeground(null);
}
}
// Now set the Window's content view with the decor
//PhoneWindow设置setContentView,后面就跟Activity的PhoneWindow设置setContentView是一样的流程。
mWindow.setContentView(subDecor);
//代码省略
}
下图是一个别人做的一个流程图,十分简单明了。
**Activity的XML解析布局**UI绘制流程
UI的绘制是在onResume方法中执行的,会通过AMS调用ActivityThread的handleResumeActivity方法执行。
ActivityThread#handleResumeActivity
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
//代码省略
final Activity a = r.activity;
//代码省略
//这里的ViewManager的实现类是WindowManagerImpl
ViewManager wm = a.getWindowManager();
//代码省略
//添加view之后,在这里面进行绘制
wm.addView(decor, l);
//代码省略
}
WindowManagerImpl#addView
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
//mGlobal是WindowManagerGlobal
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
WindowManagerGlobal#addView
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
//代码省略
ViewRootImpl root;
//代码省略
//创建ViewRootImpl
root = new ViewRootImpl(view.getContext(), display);
//代码省略
// do this last because it fires off messages to start doing things
try {
//设置view,在里面进行测量布局绘制等操作
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
//代码省略
}
ViewRootImpl#setView
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
//代码省略
//请求绘制
requestLayout();
//代码省略
}
ViewRootImpl#requestLayout
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
//遍历view
scheduleTraversals();
}
}
ViewRootImpl#scheduleTraversals
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
//执行mTraversalRunnable这个任务
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
ViewRootImpl#TraversalRunnable
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
ViewRootImpl#doTraversal
void doTraversal() {
if (mTraversalScheduled) {
//代码省略
performTraversals();
//代码省略
}
}
ViewRootImpl#performTraversals
private void performTraversals() {
//代码省略
//测量
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
//代码省略
//布局
performLayout(lp, mWidth, mHeight);
//代码省略
//绘制
performDraw();
//代码省略
}
执行完performDraw();就完成了绘制的过程了。下图是一个别人做的一个流程图,十分简单明了。
**UI的具体绘制流程**
网友评论