您的位置:首页 > 其它

Activity创建到与SurfaceComposerClient建立通信流程

2018-01-04 11:51 483 查看

1. 概述

  应用程序是通过activity来展现,那么activity是如何完成绘制并显示呢?其实应用程序的显示是和surface有关,那么activity与surface有是什么关系呢?接下来几篇文章将以这个为出发点分析,应用程序是如何一步步通过activity、surface呈现出用户界面的。

2. activity的创建

  应用启动时zygote会fork一个子进程作为APP对应的进程,它的入口函数是ActivityThread类中的main函数,acitvity的创建入口就是ActivityThread类中的方法handleLaunchActivity,其实现如下:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
。。。。。。
//见小节2.1 activity的新建
Activity a = performLaunchActivity(r, customIntent);

if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
//见小节2.2
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
} else {
// 如果出现错误,走该分支销毁
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
}
}


2.1 activity的新建

  activity的实例是在performLaunchActivity方法中创建的,并为activity创建一个phonewindow对象

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
。。。。。。
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//创建activity实例
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
。。。。。。
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//创建ContextImpl对象
Context appContext = createBaseContextForActivity(r, activity);
。。。。。。。
//与phonewindow建立关系。并做一些初始准备,见小节2.1.1
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);
//回调activity的OnCreate的方法,见2.1.2
mInstrumentation.callActivityOnCreate(activity, r.state);

if (!r.activity.mFinished) {
//回调activity的OnStart的方法
activity.performStart();
r.stopped = false;
}
return activity;
}


2.1.1 Activity的attach函数

  Activity的attach主要调用attachBaseContext函数完成ContextImpl的设置,然后创建了PhoneWindow对象、调用setCallback设置回调、调用了setWindowManager设置窗口管理者

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) {
attachBaseContext(context);//保存performLaunchActivity创建的context对象

mFragments.attachHost(null /*parent*/);

mWindow = new PhoneWindow(this);//为该activity创建PhoneWindow对象
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();

mMainThread = aThread;
mInstrumentation = instr;
mToken = token;//身份识别令牌
mIdent = ident;
mApplication = application;
mIntent = intent;
mReferrer = referrer;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;
if (voiceInteractor != null) {
if (lastNonConfigurationInstances != null) {
mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
} else {
mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
Looper.myLooper());
}
}
//创建了一个WindowManagerImpl对象,因此Activity的mWindowManager成员变量就是WindowManagerImpl对象
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();
mCurrentConfig = config;
}


2.1.2 Activity的OnCreate函数

  OnCreate方法主要是完成获取activity布局信息,为窗口绘制做准备。

@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.activity_disp);//加载布局信息
}
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);//见2.1.3
initWindowDecorActionBar();
}
public Window getWindow() {
return mWindow;//mWindow其实是activity.attach()中创建的PhoneWindow对象
}


2.1.3 PhoneWindow的setContentView函数

@Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();//创建DecorView
} 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);//获取UI布局信息
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}


因mLayoutInflater.inflate解析UI布局信息比较复杂,暂不做分析;由前面分析可用以下图形表示:



2.2 handleResumeActivity

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
//执行到onResume方法()
ActivityClientRecord r = performResumeActivity(token, clearHide);

if (r != null) {
...
if (!r.activity.mFinished && willBeVisible
&& r.activity.mDecor != null && !r.hideForNow) {
...
mNumVisibleActivities++;
if (r.activity.mVisibleFromClient) {
//添加视图[见小节2.2.1]
r.activity.makeVisible();
}
}

//resume完成
if (reallyResume) {
ActivityManagerNative.getDefault().activityResumed(token);
}
} else {
...
}
}


2.2.1 Activity.makeVisible

void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
//【见小节2.2.2】
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}


wm 是前面分析activity.attach时创建的WindowManagerImpl对象;

addView方法中的参数mDecor是前面分析phonewindow创建的DecorView。

2.2.2 WindowManagerImpl.addView

@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
//【见小节2.3】
mGlobal.addView(view, params, mDisplay, mParentWindow);
}


mGlobal 是WindowManagerGlobal对象

2.3 WMG.addView

public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) {
...
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
//创建ViewRootImpl[见小节2.4]
ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);

//[见小节2.5]
root.setView(view, wparams, panelParentView);
...
}


2.4 ViewRootImpl

public ViewRootImpl(Context context, Display display) {
mContext = context;
//获取IWindowSession的代理类【见小节2.4.1】
mWindowSession = WindowManagerGlobal.getWindowSession();
mDisplay = display;
mThread = Thread.currentThread(); //主线程
mWindow = new W(this); //【见小节2.4.3】
mChoreographer = Choreographer.getInstance();
...
}


2.4.1 WMG.getWindowSession

[-> WindowManagerGlobal.java]

public static IWindowSession getWindowSession() {
synchronized (WindowManagerGlobal.class) {
if (sWindowSession == null) {
try {
//获取IMS的代理类
InputMethodManager imm = InputMethodManager.getInstance();
//获取WMS的代理类
IWindowManager windowManager = getWindowManagerService();
//经过Binder调用,最终调用WMS[见小节2.4.2]
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {...},
imm.getClient(), imm.getInputContext());
} catch (RemoteException e) {
...
}
}
return sWindowSession
}
}


通过binder调用进入system_server进程,执行如下操作:

2.4.2 WMS.openSession

public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) {
//创建Session对象
Session session = new Session(this, callback, client, inputContext);
return session;
}


再次经过Binder将数据写回app进程,则获取的便是Session的代理对象。

2.4.3 创建对象W

[-> ViewRootImpl.java ::W]

static class W extends IWindow.Stub {
private final WeakReference<ViewRootImpl> mViewAncestor;
private final IWindowSession mWindowSession;

W(ViewRootImpl viewAncestor) {
mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
mWindowSession = viewAncestor.mWindowSession;
}
...
}


创建完ViewRootImpl对象后,再回到小节2.4,接下来调用该对象的setView方法。

2.5 ViewRootImpl.setView

[-> ViewRootImpl.java]

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
...
//通过Binder调用,进入system进程的Session[见小节2.6]
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
...
}
}


通过Binder调用,进入system_server进程的Session对象

2.6 Session.addToDisplay

[-> Session.java]

final class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {

public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {
//[见小节2.7]
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
outContentInsets, outStableInsets, outOutsets, outInputChannel);
}
}


2.7 WMS.addWindow

[-> WindowManagerService.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) {
...
WindowToken token = mTokenMap.get(attrs.token);
//创建WindowState【见小节2.7.1】
WindowState win = new WindowState(this, session, client, token,
attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
...
//调整WindowManager的LayoutParams参数
mPolicy.adjustWindowParamsLw(win.mAttrs);
res = mPolicy.prepareAddWindowLw(win, attrs);
addWindowToListInOrderLocked(win, true);
// 设置input
mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
//【见小节2.7.2】
win.attach();
mWindowMap.put(client.asBinder(), win);
...
}


2.7.1 WindowState

[-> WindowState.java]

WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a,
int viewVisibility, final DisplayContent displayContent) {
mService = service;
mSession = s; //Session的Binder服务端
mClient = c;  //IWindow的Binder代理端
mToken = token;
mOwnerUid = s.mUid; //所对应app的uid
...
DeathRecipient deathRecipient = new DeathRecipient();
c.asBinder().linkToDeath(deathRecipient, 0); //app端死亡则会有死亡回调

WindowState appWin = this;
WindowToken appToken = appWin.mToken;
while (appToken.appWindowToken == null) {
WindowToken parent = mService.mTokenMap.get(appToken.token);
if (parent == null || appToken == parent) {
break;
}
appToken = parent;
}
mAppToken = appToken.appWindowToken;

//创建WindowStateAnimator对象
mWinAnimator = new Windo
b631
wStateAnimator(this);
//创建InputWindowHandle对象
mInputWindowHandle = new InputWindowHandle(
mAppToken != null ? mAppToken.mInputApplicationHandle : null, this,
displayContent.getDisplayId());
}


WindowState持有远程app进程中IWindow.Stub的代理,并且注册了死亡回调,当app进程死亡则会收到相应的死亡通知。

2.7.2 WS.attach

[-> WindowState.java]

void attach() {
//【见小节2.7.3】
mSession.windowAddedLocked();
}


2.7.3 windowAddedLocked

[-> Session.java]

void windowAddedLocked() {
if (mSurfaceSession == null) {
//【见小节2.7.4】
mSurfaceSession = new SurfaceSession();
mService.mSessions.add(this);
if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
mService.dispatchNewAnimatorScaleLocked(this);
}
}
mNumWindow++;
}


创建SurfaceSession对象,并将当前Session添加到WMS.mSessions成员变量。

2.7.4 nativeCreate

[-> android_view_SurfaceSession.cpp]

static jlong nativeCreate(JNIEnv* env, jclass clazz) {
SurfaceComposerClient* client = new SurfaceComposerClient();
client->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(client);
}


创建SurfaceComposerClient对象, 作为跟SurfaceFlinger通信的代理对象。

3.总结

  本文分析了activity如何一步步地从创建到获得surfaceflinger通信的代理对象,后面将继续分析activity如何绘制并通过SurfaceComposerClient传递给surfaceflinger显示到屏幕上。未完待续。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息