android 那点事儿 申请了群330513862,有兴趣的童鞋可以加入,大家一起学习、研讨、分享经验。
首先我们要说一下Surface是什么?关于Surface的描述是这样的“Handle onto a raw buffer that is being managed by the screen compositor.”简单翻译就是“由屏幕显示内容合成器所管理的原始缓存区的句柄”。
1、Surface是一个句柄,通过Surface就可以获得原始缓冲器及其内容。
2、a raw buffer 原始缓冲区是用于保存当前窗口的像素数据。
3、Suffer中有一个Canvas成员专门用于画图。
接着我们就开始说说Surface的创建过程:我们之前讲过,在Activity创建到一定阶段的时候会走到ActivityThread类的handleLaunchActivity方法中,今天我们就从这里开始讲解。在这个方法中会创建一个Activity对象
Activity a = performLaunchActivity(r, customIntent);
我们去performLaunchActivity这个方法中查看,首先创建一个Activity
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
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);
}
}
然后创建Application之后就会走到
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
最终把activity给了ActivityClientRecord
r.activity = activity;
这些我们之前都讲解过,这里不在多做赘述,我们只看activity.attach这一步
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) {
attachBaseContext(context);
mFragments.attachActivity(this);
mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(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;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;
mWindow.setWindowManager(null, mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
}
在这里先new了一个新的Window
mWindow = PolicyManager.makeNewWindow(this);
然后做了一些初始化工作,接着就是一些变量的赋值,最后走到
mWindow.setWindowManager(null, mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
这里面做了什么工作呢?
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
boolean hardwareAccelerated) {
mAppToken = appToken;
mAppName = appName;
if (wm == null) {
wm = WindowManagerImpl.getDefault();
}
mWindowManager = new LocalWindowManager(wm, hardwareAccelerated);
}
首先去获取了一个WindowManager,WindowManagerImpl.getDefault()也就是
public static WindowManagerImpl getDefault() {
return sWindowManager;
}
返回的其实是一个WindowManagerImpl,它实现了WindowManager接口,然后创建了mWindowManager = new LocalWindowManager(wm, hardwareAccelerated),LocalWindowManager是什么呢?它继承于WindowManagerImpl.CompatModeWrapper而CompatModeWrapper又实现了WindowManager接口,我们接着看LocalWindowManager的构造函数
LocalWindowManager(WindowManager wm, boolean hardwareAccelerated) {
super(wm, getCompatInfo(mContext));
mHardwareAccelerated = hardwareAccelerated ||
SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
}
然后是super(wm, getCompatInfo(mContext))也就是
CompatModeWrapper(WindowManager wm, CompatibilityInfoHolder ci) {
mWindowManager = wm instanceof CompatModeWrapper
? ((CompatModeWrapper)wm).mWindowManager : (WindowManagerImpl)wm;
// Use the original display if there is no compatibility mode
// to apply, or the underlying window manager is already a
// compatibility mode wrapper. (We assume that if it is a
// wrapper, it is applying the same compatibility mode.)
if (ci == null) {
mDefaultDisplay = mWindowManager.getDefaultDisplay();
} else {
//mDefaultDisplay = mWindowManager.getDefaultDisplay();
mDefaultDisplay = Display.createCompatibleDisplay(
mWindowManager.getDefaultDisplay().getDisplayId(), ci);
}
mCompatibilityInfo = ci;
}
最终我们的mWindowManager还以一个WindowManagerImpl然后我们还是回到activity.attach中,在mWindow.setWindowManager之后mWindowManager = mWindow.getWindowManager()所以我们这里的mWindowManager其实就是一个WindowManagerImpl。分析到这里我们就不再做