一
目的
本节的目的就是为了讲清楚
Android
中的
Surface
系统,大家耳熟能详的
SurfaceFlinger
到底是个什么东西,它的工作流程又是怎样的。当然,鉴于
SurfaceFlinger
的复杂性,我们依然将采用情景分析的办法,找到合适的切入点。
一个
Activity
是怎么在屏幕上显示出来的呢?我将首先把这个说清楚。
接着我们把其中的关键调用抽象在
Native
层,以这些函数调用为切入点来研究
SurfaceFlinger
。好了,开始我们的征途吧。
二
Activity
是如何显示的
最初的想法就是,
Activity
获得一块显存,然后在上面绘图,最后交给设备去显示。这个道理是没错,但是
Android
的
SurfaceFlinger
是在
System Server
进程中创建的,
Activity
一般另有线程,这之间是如何
...
如何挂上关系的呢?我可以先提前告诉大家,这个过程还比较复杂。呵呵。
好吧,我们从
Activity
最初的启动开始。代码在
framework/base/core/java/android/app/ActivityThread.java
中,这里有个函数叫
handleLaunchActivity
[---->ActivityThread:: handleLaunchActivity()]
private final void handleLaunchActivity(ActivityRecord r, Intent customIntent) {
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward);
---->
调用handleResumeActivity
}
handleLaunchActivity
中会调用
handleResumeActivity
。
[--->ActivityThread:: handleResumeActivity]
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
boolean willBeVisible = !a.mStartedActivity;
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
wm.addView(decor, l); //
这个很关键。
}
上面
addView
那几行非常关键,它关系到咱们在
Activity
中
setContentView
后,整个
Window
到底都包含了些什么。我先告诉大家。所有你创建的
View
之上,还有一个
DecorView
,这是一个
FrameLayout
,另外还有一个
PhoneWindow
。上面这些东西的代码在
framework/Policies/Base/Phone/com/android/Internal/policy/impl
。这些隐藏的
View
的创建都是由你在
Acitivty
的
onCreate
中调用
setContentView
导致的。
[---->PhoneWindow:: addContentView]
public void addContentView(View view, ViewGroup.LayoutParams params) {
if (mContentParent == null) {
//
刚创建的时候mContentParent
为空
installDecor();
}
mContentParent.addView(view, params);
final Callback cb = getCallback();
if (cb != null) {
cb.onContentChanged();
}
}
installDecor
将创建mDecor
和mContentParent
。mDecor
是DecorView
类型,
mContentParent
是ViewGroup
类型
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
那么,
ViewManager wm = a.getWindowManager()
又返回什么呢?
PhoneWindow
从
Window
中派生,
Acitivity
创建的时候会调用它的
setWindowManager
。而这个函数由
Window
类实现。
代码在
framework/base/core/java/android/view/Window.java
中
public void setWindowManager(WindowManager wm,IBinder appToken, String appName) {
mAppToken = appToken;
mAppName = appName;
if (wm == null) {
wm = WindowManagerImpl.getDefault();
}
mWindowManager = new LocalWindowManager(wm);
}
你看见没,分析
JAVA
代码这个东西真的很复杂。
mWindowManager
的实现是
LocalWindowManager
,但由通过
Bridge
模式把功能交给
WindowManagerImpl
去实现了。
真的很复杂!
好了,罗里罗嗦的,我们回到
wm.addView(decor, l)
。最终会由
WindowManagerImpl
来完成
addView
操作,我们直接看它的实现好了。
代码在
framework/base/core/java/android/view/WindowManagerImpl.java
[---->addView]
private void addView(View view, ViewGroup.LayoutParams params, boolean nest)
{
ViewRoot root; //ViewRoot
,我们的主人公终于登场!
synchronized (this) {
root = new ViewRoot(view.getContext());
root.mAddNesting = 1;
view.setLayoutParams(wparams);
if (mViews == null) {
index = 1;
mViews = new View[1];
mRoots = new ViewRoot[1];
mParams = new WindowManager.LayoutParams[1];
} else {
}
index--;
mViews[index] = view;
mRoots[index] = root;
mParams[index] = wparams;
}
root.setView(view, wparams, panelParentView);
}
ViewRoot
是整个显示系统中最为关键的东西,看起来这个东西好像和
View
有那么点关系,其实它根本和
View
等
UI
关系不大,它不过是一个
Handler
罢了,唯一有关系的就是它其中有一个变量为
Surface
类型。我们看看它的定义。
ViewRoot
代码在
framework/base/core/java/android/view/ViewRoot.java
中
public final class ViewRoot extends Handler implements ViewParent,
View.AttachInfo.Callbacks
{
private final Surface mSurface = new Surface();
}
它竟然从handler
派生,而ViewParent
不过定义了一些接口函数罢了。
看到
Surface
直觉上感到它和
SurfaceFlinger
有点关系。要不先去看看?
Surface
代码在
framework/base/core/java/android/view/Surface.java
中,我们调用的是无参构造函数。
public Surface() {
mCanvas = new CompatibleCanvas(); //
就是创建一个Canvas
!
}
如果你有兴趣的话,看看
Surface
其他构造函数,最终都会调用
native
的实现,而这些
native
的实现将和
SurfaceFlinger
建立关系,但我们这里
ViewRoot
中的
mSurface
显然还没有到这一步。那它到底是怎么和
SurfaceFlinger
搞上的呢?这一切待会就会水落石出的。
另外,为什么
ViewRoot
是主人公呢?因为
ViewRoot
建立了客户端和
SystemServer
的关系。我们看看它的构造函数。
public ViewRoot(Context context) {
super();
....
getWindowSession(context.getMainLooper());
}
getWindowsession
将建立和WindowManagerService
的关系。
ublic static IWindowSession getWindowSession(Looper mainLooper) {
synchronized (mStaticInit) {
if (!mInitialized) {
try {
//sWindowSession
是通过Binder
机制创建的。终于让我们看到点希望了
InputMethodManager imm = InputMethodManager.getInstance(mainLooper);
sWindowSession = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"))
.openSession(imm.getClient(), imm.getInputContext());
mInitialized = true;
} catch (RemoteException e) {
}
}
return sWindowSession;
}
}
上面跨
Binder
的进程调用另一端是
WindowManagerService
,代码在
framework/base/services/java/com/android/server/WindowManagerService.java
中。我们先不说这个。
回过头来看看
ViewRoot
接下来的调用。
[-->ViewRoot::setView()]
,这个函数很复杂,我们看其中关键几句。
public void setView(View view, WindowManager.LayoutParams attrs,
View panelParentView) {
synchronized (this) {
requestLayout();
try {
res = sWindowSession.add(mWindow, mWindowAttributes,
getHostVisibility(), mAttachInfo.mContentInsets);
}
}
requestLayout
实现很简单,就是往
handler
中发送了一个消息。
public void requestLayout() {
checkThread();
mLayoutRequested = true;
scheduleTraversals(); //
发送DO_TRAVERSAL
消息
}
public void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
sendEmptyMessage(DO_TRAVERSAL);
}
}
我们看看跨进程的那个调用。
sWindowSession.add
。它的最终实现在
WindowManagerService
中。
[--->WindowSession::add()]
public int add(IWindow window, WindowManager.LayoutParams attrs,
int viewVisibility, Rect outContentInsets) {
return addWindow(this, window, attrs, viewVisibility, outContentInsets);
}
WindowSession
是个内部类,会调用外部类的
addWindow
这个函数巨复杂无比,但是我们的核心目标是找到创建显示相关的部分。所以,最后精简的话就简单了。
[--->WindowManagerService:: addWindow]
public int addWindow(Session session, IWindow client,
WindowManager.LayoutParams attrs, int viewVisibility,
Rect outContentInsets) {
//
创建一个WindowState
,这个又是什么玩意儿呢?
win = new WindowState(session, client, token,
attachedWindow, attrs, viewVisibility);
win.attach();
return res;
}
WindowState
类中有一个和
Surface
相关的成员变量,叫
SurfaceSession
。它会在
attach
函数中被创建。
SurfaceSession
嘛,就和
SurfaceFlinger
有关系了。我们待会看。
好,我们知道
ViewRoot
创建及调用
add
后,我们客户端的
View
系统就和
WindowManagerService
建立了牢不可破的关系。
另外,我们知道
ViewRoot
是一个
handler
,而且刚才我们调用了
requestLayout
,所以接下来消息循环下一个将调用的就是
ViewRoot
的
handleMessage
。
public void handleMessage(Message msg) {
switch (msg.what) {
case DO_TRAVERSAL:
performTraversals();
performTraversals
更加复杂无比,经过我仔细挑选,目标锁定为下面几个函数。当然,后面我们还会回到
performTraversals
,不过我们现在更感兴趣的是
Surface
是如何创建的。
private void performTraversals() {
// cache mView since it is used so much below...
final View host = mView;
boolean initialized = false;
boolean contentInsetsChanged = false;
boolean visibleInsetsChanged;
try {
//ViewRoot
也有一个Surface
成员变量,叫mSurface
,这个就是代表SurfaceFlinger
的客户端
//ViewRoot
在这个Surface
上作画,最后将由SurfaceFlinger
来合成显示。刚才说了mSurface
还没有什么内容。
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
[---->ViewRoot:: relayoutWindow()]
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
//relayOut
是跨进程调用,mSurface
做为参数传进去了,看来离真相越来越近了呀!
int relayoutResult = sWindowSession.relayout(
mWindow, params,
(int) (mView.mMeasuredWidth * appScale + 0.5f),
(int) (mView.mMeasuredHeight * appScale + 0.5f),
viewVisibility, insetsPending, mWinFrame,
mPendingContentInsets, mPendingVisibleInsets,
mPendingConfiguration, mSurface); mSurface
做为参数传进去了。
}
我们赶紧转到
WindowManagerService
去看看吧。、
public int relayoutWindow(Session session, IWindow client,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, boolean insetsPending,
Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Configuration outConfig, Surface outSurface){
.....
try {
//
看到这里,我内心一阵狂喜,有戏,太有戏了!
//
其中win
是我们最初创建的WindowState
!
Surface surface = win.createSurfaceLocked();
if (surface != null) {
//
先创建一个本地surface
,然后把传入的参数outSurface copyFrom
一下
outSurface.copyFrom(surface);
win.mReportDestroySurface = false;
win.mSurfacePendingDestroy = false;
} else {
outSurface.release();
}
}
}
[--->WindowState::createSurfaceLocked]
Surface createSurfaceLocked() {
try {
mSurface = new Surface(
mSession.mSurfaceSession, mSession.mPid,
mAttrs.getTitle().toString(),
0, w, h, mAttrs.format, flags);
}
Surface.openTransaction();
这里使用了
Surface
的另外一个构造函数。
public Surface(SurfaceSession s,
int pid, String name, int display, int w, int h, int format, int flags)
throws OutOfResourcesException {
mCanvas = new CompatibleCanvas();
init(s,pid,name,display,w,h,format,flags); ---->
调用了native
的init
函数。
mName = name;
}
到这里,不进入
JNI
是不可能说清楚了。不过我们要先回顾下之前的关键步骤。
l
add
中,
new
了一个
SurfaceSession
l
创建
new
了一个
Surface
l
调用
copyFrom
,把本地
Surface
信息传到
outSurface
中
JNI
层
上面两个类的
JNI
实现都在
framework/base/core/jni/android_view_Surface.cpp
中。
[---->SurfaceSession:: SurfaceSession()]
public class SurfaceSession {
/** Create a new connection with the surface flinger. */
public SurfaceSession() {
init();
}
它的
init
函数对应为:
[--->SurfaceSession_init]
static void SurfaceSession_init(JNIEnv* env, jobject clazz)
{
//SurfaceSession
对应为SurfaceComposerClient
sp<SurfaceComposerClient> client = new SurfaceComposerClient;
client->incStrong(clazz);
//Google
常用做法,在JAVA
对象中保存C++
对象的指针。
env->SetIntField(clazz, sso.client, (int)client.get());
}
Surface
的
init
对应为:
[--->Surface_init]
static void Surface_init(
JNIEnv* env, jobject clazz,
jobject session,
jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jint flags)
{
SurfaceComposerClient* client =
(SurfaceComposerClient*)env->GetIntField(session, sso.client);
sp<SurfaceControl> surface;
if (jname == NULL) {
</
分享到:
相关推荐
### Android深入浅出之Surface详解 #### 一、引言 在深入了解Android系统中的Surface机制之前,我们需要明确几个核心概念。在Android系统中,Surface是一个关键的概念,它主要用于描述一个可以绘制图像的区域,...
在深入学习Surface时,可以参考提供的资源,如《详解Android Surface系统 - OPhoneAndroid技术讨论区 - 中国移动MM论坛.html》和《Android深入浅出之Surface.pdf》,这些资料将详细介绍Surface的原理、最佳实践以及...
包括《Android_图形系统分析-surfaceFlinger流程.doc》、《Android_Surfaceflinger研究-显示系统.pdf》、《Surfaceflinger详解.pdf》、《Android核心分析.pdf》和《Android深入浅出之Surface.pdf》,它们涵盖了从...
接着,使用FFmpeg解码出的YUV或者其他格式的像素数据,通过ANativeWindow_Buffer结构体更新到Surface上,实现视频的显示。 6. **视频帧的处理**:从FFmpeg解码出来的原始视频帧通常是YUV格式,需要进行色彩空间转换...
本教程将深入探讨如何使用SurfaceTexture来实现自定义相机预览,并在PictureCallback回调中保存图片。 首先,了解SurfaceTexture的基本概念。SurfaceTexture是一个抽象接口,它与OpenGL ES纹理绑定,允许将硬件图形...
android 通过surfacetexture绘制Bitmap,使用ISurfaceComposerClient创建新图层
这个压缩包“Android-Surface-.rar”包含了对Android Surface的深入学习资料,非常适合开发者进行参考学习。让我们一起深入了解Surface及其在Android开发中的作用。 首先,Surface是Android系统中的一个抽象接口,...
在Android系统中,Surface是用来处理图形绘制的核心组件,它提供了硬件加速的图形渲染接口,使得开发者可以在不阻塞用户界面的情况下进行高效的图像处理。在这个项目中,我们将关注如何使用C语言来调用Surface来实现...
"android glsurface example"就是关于如何在Android应用中使用GLSurfaceView和OpenGL ES进行图形渲染的一个示例项目。 GLSurfaceView类为开发者提供了一个框架,它处理了大部分与创建和管理OpenGL渲染线程、同步与...
Android平台 将 GL_TEXTURE_2D纹理 渲染到 Surface 上 案例实现文章介绍: https://xiaxl.blog.csdn.net/article/details/131682521 技术实现流程大致如下: 1、OpenGLES3中加载GL_TEXTURE_2D纹理,生成纹理ID; 2...
在Android开发中,实现"android surface 背景透明,图片拖拉"的功能涉及到多个关键知识点,这将为用户提供一种交互式的地图编辑体验。以下是对这些技术要点的详细解释: 1. **SurfaceView**: SurfaceView是Android...
Android Surface Android Surface 是 Android 操作系统中的图形系统组件,负责提供图形绘制和显示功能。在 Android 中,Surface 是一个可供图形系统绘制的 surface,能够支持 2D 和 3D 图形绘制。下面将对 Android ...
通过深入研究这一过程,可以更好地理解Surface架构的工作原理。 #### WindowManagerService (WMS) WMS是在System_Server进程中启动的一项核心服务,它负责管理应用程序窗口的创建、控制以及消息的收集与分发。当...
"Android Surface画图游戏 示例代码"提供了一个完整的工程实例,可以帮助开发者深入理解如何利用SurfaceView及其相关组件来实现游戏的图形渲染。下面我们将详细探讨这个示例项目中的关键知识点。 1. **Android ...
本示例“android mediacodec surface sample”主要关注如何使用MediaCodec API来解码H264编码的MP4视频,并将解码后的视频帧渲染到Surface上。以下是对这个示例涉及的知识点的详细解释: 1. **MediaCodec**:...
本文将详细解析"android socket surface mediacodec h264"这个主题,涵盖如何通过Socket接收视频流数据,并利用Surface和MediaCodec进行解码与播放。 首先,Socket是网络通信的基础,它提供了进程间的数据传输通道...
第8章深入讲解了Surface系统的实现原理,分析了Surface与Activity之间以及Surface与SurfaceFlinger之间的关系、SurfaceFlinger的工作原理、Surface系统中的帧数据传输以及LayerBuffer的工作流程。第9章对Vold和Rild...
本文档旨在为那些已经具备一定Android基础知识的学习者提供深入理解`Surface`及其相关组件的工作原理。 #### 二、Surface 的概念 `Surface` 可以简单地理解为一个可被多个线程安全访问的图形缓冲区。它是Android...
深入理解Android 卷1 不是扫描版的,是全版电子书的,非PDF,可编辑,各种阅览器以打开!包括书签和同步目录! 第1章 阅读前的准备工作 / 1 1.1 系统架构 / 2 1.1.1 Android系统架构 / 2 1.1.2 本书的架构 / 3 1.2 ...
在Android开发中,多媒体播放是常见的功能之一,`MediaPlayer` 和 `SurfaceView` 的结合使用是实现视频播放的标准方式。本篇文章将详细讲解如何利用这两个组件来构建一个视频播放器。 首先,`MediaPlayer` 是...