本系列是基于android Q即android10
SurfaceFlinger学习笔记(一)应用启动流程
SurfaceFlinger学习笔记(二)之Surface
SurfaceFlinger学习笔记(三)之SurfaceFlinger进程
SurfaceFlinger学习笔记(四)之HWC2
SurfaceFlinger学习笔记(五)之HWUI
SurfaceFlinger学习笔记(六)之View Layout Draw过程分析
用户在Launcher程序里点击应用图标时,会通知ActivityManagerService启动应用的入口Activity,ActivityManagerService则会通知Zygote进程孵化出应用进程,然后在这个应用进程里执行ActivityThread的main方法。应用进程接下来通知ActivityManagerService应用进程已启动,ActivityManagerService保存应用进程的一个代理对象,这样ActivityManagerService可以通过这个代理对象控制应用进程,然后ActivityManagerService通知应用进程创建入口Activity的实例,并执行它的生命周期方法
frameworks/base/core/java/android/app/Instrumentation.java
用于实现应用程序测试代码的基类。当在打开仪器的情况下运行时,这个类将在任何应用程序代码之前为您实例化,允许您监视系统与应用程序的所有交互。可以通过AndroidManifest.xml的标签描述该类的实现。
frameworks/base/core/java/android/app/ActivityManager.java
该类提供与Activity、Service和Process相关的信息以及交互方法, 可以被看作是ActivityManagerService的辅助类。
frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java
Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作。在SDK-29(android10)之后,抛弃了曾经的ActivityManagerService,改用ActivityTaskManagerService
frameworks/base/core/java/android/app/ActivityThread.java
管理应用程序进程中主线程的执行,根据Activity管理者的请求调度和执行activities、broadcasts及其相关的操作。
frameworks\base\services\core\java\com\android\server\wm\ActivityStack.java
负责单个Activity栈的状态和管理。
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。
frameworks\base\services\core\java\com\android\server\wm\ClientLifecycleManager.java
用来管理多个客户端生命周期执行请求的管理类。
* frameworks/base/core/java/android/app/Activity.java
public void startActivityForResult( String who, Intent intent, int requestCode, @Nullable Bundle options) {
。。。
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, who, intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(mToken, who, requestCode, ar.getResultCode(), ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
。。。
}
* frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
。。。
// SDK-28
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
// SDK-29
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
。。。
}
ActivityTaskManager.getService()返回的是IActivityTaskManager接口,这是远程调用的接口,执行IActivityTaskManager#startActivity之后相当于当前线程将启动Activity的消息发送出去了
* frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")--构造ActivityStarter
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId) -- 注意这个方法,在这个方法里有一句 mRequest.mayWait = true;
.execute();
}
* frameworks\base\services\core\java\com\android\server\wm\RootActivityContainer.java
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
。。。。
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
。。。
if (!resumedOnDisplay) {
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}
return result;
}
* frameworks\base\services\core\java\com\android\server\wm\ActivityStack.java
boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// ......
boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, false);
}
// ......
if (next.attachedToProcess()) {
try {
// ......
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
getDisplay().mDisplayContent.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
} catch (Exception e) {
// ......
mStackSupervisor.startSpecificActivityLocked(next, true, false);
return true;
}
// ......
} else {
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
next.showStartingWindow(null /* prev */, false /* newTask */,
false /* taskSwich */);
}
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
// ......
if (prev.attachedToProcess()) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLogTags.writeAmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving);
mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
// ......
}
}
// ......
}
栈顶Activity执行onPause方法退出流程
* frameworks\base\services\core\java\com\android\server\wm\ActivityStack.java
//PauseActivityItem对象将会在后面的IPC过程中传到Activity所在的进程
mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
* frameworks\base\core\java\android\app\servertransaction\ClientTransaction.java
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
* frameworks\base\core\java\android\app\ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
}
* frameworks\base\core\java\android\app\ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
* frameworks\base\core\java\android\app\ActivityThread.java
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);
}
///////////////////////
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();
}
break;
*frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java
public void execute(ClientTransaction transaction) {
// ......
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
// ......
// Cycle to the state right before the final requested state.
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
* frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
Activity所在的应用进程启动过程
* frameworks\base\services\core\java\com\android\server\wm\ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
knownToBeDead = true;
}
// ......
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);//mService为ActivityTaskManagerService
// ......
}
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService
final class LocalService extends ActivityManagerInternal{
// ...省略部分代码
@Override
public void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, String hostingType, ComponentName hostingName) {
synchronized (ActivityManagerService.this) {
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName),
false /* allowWhileBooting */, false /* isolated */,
true /* keepIfLarge */);
}
}
// ...省略部分代码
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
}
frameworks\base\core\java\android\os\Process
frameworks\base\core\java\android\os\ZygoteProcess
public static void main(String[] args) {
.....
Looper.prepareMainLooper();
.....
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {
...
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) {
Slog.w(TAG, "Exception in new application when starting activity "
+ top.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
....
}
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
try {
if (!proc.hasThread()) {
throw new RemoteException();
}
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
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);
//...
} catch (RemoteException e) {
//...
}
} finally {
endDeferResume();
}
// ......
return true;
}
frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
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);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
// frameworks/base/core/java/android/app/ActivityThread.java
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
// ......
final Activity a = performLaunchActivity(r, customIntent);
// ......
return a;
}
* frameworks/base/core/java/android/app/ActivityThread.java
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
。。。。
ContextImpl appContext = createBaseContextForActivity(r);
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//源文件为Instrumentation.java, 它在newActivity函数中根据Activity的类名通过Java反射机制来创建对应的Activity
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);
。。。。。
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
//下面这个函数会调用Activity的onCreate函数
if (r.isPersistable()) {
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) {
throw e;
} catch (Exception e) {
。。。。
}
return activity;
}
frameworks/base/core/java/android/app/Instrumentation.java
public Activity newActivity(Class<?> clazz, Context context,
IBinder token, Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
Object lastNonConfigurationInstance) throws InstantiationException,
IllegalAccessException {
Activity activity = (Activity)clazz.newInstance();
//关键函数attach!!
ActivityThread aThread = null;
// Activity.attach expects a non-null Application Object.
if (application == null) {
application = new Application();
}
activity.attach(context, aThread, this, token, 0 /* ident */, application, intent,
info, title, parent, id,
(Activity.NonConfigurationInstances)lastNonConfigurationInstance,
new Configuration(), null /* referrer */, null /* voiceInteractor */,
null /* window */, null /* activityConfigCallback */, null /*assistToken*/);
return activity;
}
@UnsupportedAppUsage
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
attachBaseContext(context);
。。。
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
if (info.uiOptions != 0) {
mWindow.setUiOptions(info.uiOptions);
}
mUiThread = Thread.currentThread();
。。。。
mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
。。。。
}
* frameworks/base/core/java/android/view/Window.java
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
boolean hardwareAccelerated) {
mAppToken = appToken;
mAppName = appName;
mHardwareAccelerated = hardwareAccelerated;
if (wm == null) {
wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
}
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}
* frameworks/base/core/java/android/app/Activity.java
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
public Window getWindow() {
return mWindow;
}
* frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
@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();
}
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
// 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.
//mContentParent是一个ViewGroup类型,它从View中派生,所以也是一个UI单元
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
view.setLayoutParams(params);
final Scene newScene = new Scene(mContentParent, view);
transitionTo(newScene);
} else {
mContentParent.addView(view, params);
}
}
12. PhoneWindow的setContentView调用installDecor创建mDecor,它为DecorView类型,从FrameLayout派生
Activity所在的应用进程Resume过程
* frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,String reason) {
...
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
.....
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
//获得一个View对象
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
//获得ViewManager对象
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
// Normally the ViewRoot sets up callbacks with the Activity
// in addView->ViewRootImpl#setView. If we are instead reusing
// the decor view we have to notify the view root that the
// callbacks may have changed.
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
//把刚才的decor对象加入到ViewManager中
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}
} else if (!willBeVisible) {
r.hideForNow = true;
}
...
// The window is now visible if it has been added, we are not
// simply finishing, and we are not starting another activity.
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
...
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
!= forwardBit) {
l.softInputMode = (l.softInputMode
& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
| forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
}
}
...
}
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
* frameworks/base/core/java/android/view/WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
...
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
...
ViewRootImpl root;
...
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
//setView,其中view是刚才我们介绍的DecorView
root.setView(view, wparams, panelParentView);
}
3. ViewRootImpl有一个成员变量叫mSurface,它是Surface类型,负责SurfaceFlinger交互,还有一个W类型的mWindow和一个View类型的mView变量,W是ViewRootImpl定义的一个静态内部类继承IWindow.Stub,是IWindow的Bn端,负责WMS回调到应用进程用的,初始化时getWindowSession在WindowManagerService创建一个session,然后再次经过 Binder 将数据写回 app 进程,则获取的便是 Session 的代理对象 IWindowSession,这个会话被App进程用于和WMS通信
* frameworks/base/core/java/android/view/ViewRootImpl.java
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
...
final Surface mSurface = new Surface(); //创建 Surface,此时 Surface 创建完什么都没有,详见下面分析
...
public ViewRootImpl(Context context, Display display) {
mContext = context;
//获取 IWindowSession 的代理类
mWindowSession = WindowManagerGlobal.getWindowSession();
mDisplay = display;
mThread = Thread.currentThread(); //主线程
mWindow = new W(this);
mChoreographer = Choreographer.getInstance();
...
}
}
* frameworks/base/core/java/android/view/WindowManagerGlobal.java
public static IWindowSession getWindowSession() {
。。。
IWindowManager windowManager = getWindowManagerService();
//经过 Binder 调用,最终调用 WMS
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {
@Override
public void onAnimatorScaleChanged(float scale) {
ValueAnimator.setDurationScale(scale);
}
});
。。。
return sWindowSession;
}
* frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public IWindowSession openSession(IWindowSessionCallback callback) {
return new Session(this, callback);
}
* frameworks/base/core/java/android/view/ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
requestLayout(); //详见下面分析
...
//通过 Binder调用,进入 system 进程的 Session
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
...
}
}
* frameworks/base/services/core/java/com/android/server/wm/Session.java
lass Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets,
Rect outStableInsets, Rect outOutsets,
DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
InsetsState outInsetsState) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,
outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel,
outInsetsState);
}
}
* frameworks/base/core/java/android/view/ViewRootImpl.java
public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {
...
final WindowState win = new WindowState(this, session, client, token, parentWindow,
appOp[0], seq, attrs, viewVisibility, session.mUid,
session.mCanAddInternalSystemWindow);
...
WindowToken token = displayContent.getWindowToken(
hasParent ? parentWindow.mAttrs.token : attrs.token);
...
final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
displayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(),
Binder.getCallingUid());
win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
res = displayPolicy.prepareAddWindowLw(win, attrs);
final WindowState win = new WindowState(this, session, client, token, parentWindow,
appOp[0], seq, attrs, viewVisibility, session.mUid,
session.mCanAddInternalSystemWindow);
...
win.attach();
mWindowMap.put(client.asBinder(), win);
...
win.applyAdjustForImeIfNeeded();
...
if (win.canReceiveKeys()) {
//当该窗口能接收按键事件,则更新聚焦窗口
focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
false /*updateInputWindows*/);
...
}
win.getParent().assignChildLayers();
frameworks/base/services/core/java/com/android/server/wm/WindowState.java
void attach() {
mSession.windowAddedLocked(mAttrs.packageName);
}
frameworks/base/services/core/java/com/android/server/wm/Session.java
void windowAddedLocked(String packageName) {
mPackageName = packageName;
mRelayoutTag = "relayoutWindow: " + mPackageName;
if (mSurfaceSession == null) {
if (WindowManagerService.localLOGV) Slog.v(
TAG_WM, "First window added to " + this + ", creating SurfaceSession");
mSurfaceSession = new SurfaceSession();
if (SHOW_TRANSACTIONS) Slog.i(
TAG_WM, " NEW SURFACE SESSION " + mSurfaceSession);
mService.mSessions.add(this);
if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
mService.dispatchNewAnimatorScaleLocked(this);
}
}
mNumWindow++;
}
* frameworks/base/core/jni/android_view_SurfaceSession.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
SurfaceComposerClient* client = new SurfaceComposerClient();
client->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(client);
}
* frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
//getComposerService() 将返回 SF 的 Binder 代理端的 BpSurfaceFlinger 对象
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
sp<ISurfaceComposerClient> conn;
//先调用 SF 的 createConnection()
conn = sf->createConnection();
if (conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
下面内容请参考SurfaceFlinger学习笔记(二)之HWUI
- WMS所在的SystemServer进程接收到按键事件
- WMS找到UI位于屏幕顶端的进程所对应的IWindow对象,这是一个Bp端对象
- 调用这个IWindow对象的dispatchKey。IWindow对象的Bn端位于ViewRootImpl 中,ViewRootImpl 再根据内部View的位置信息找到真正处理这个事件的View,最后调用dispatchKey函数完成按键的处理
- 在Windows中应用程序的按键处理流程是每一个按键事件都会转化成一个消息,这个消息将由系统加入到对应进程的消息队列中。该进程的消息在派发处理时,会根据消息的句柄找到对应的Window(窗口),继而该消息就由这个Window处理了
* frameworks/base/core/java/android/view/ViewRootImpl.java
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
。。。
}
}
private void performTraversals() {
final View host = mView;//这个mView就是DecorView
。。。
boolean hwInitialized = false;
boolean contentInsetsChanged = false;
boolean hadSurface = mSurface.isValid();
。。。
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
。。。
performDraw();
}
* frameworks/base/core/java/android/view/ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
。。。
//调用IWindowSession的relayOut
int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,
mPendingMergedConfiguration, mSurfaceControl, mTempInsets);
if (mSurfaceControl.isValid()) {
mSurface.copyFrom(mSurfaceControl);
} else {
destroySurface();
}
。。。
}
private boolean draw(boolean fullRedrawNeeded) {
Surface surface = mSurface;
。。。
if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset,
scalingRequired, dirty, surfaceInsets)) {
return false;
}
。。。。
}
private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
boolean scalingRequired, Rect dirty, Rect surfaceInsets) {
// // Draw with software renderer.
final Canvas canvas;
。。。
canvas = mSurface.lockCanvas(dirty);//从mSurface中lock一块Canvas
。。。
mView.draw(canvas);//调用DecorView的draw函数
。。。
surface.unlockCanvasAndPost(canvas);
}