Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程资料

合集下载

Android系统Surface机制的SurfaceFlinger服务的线程模型分析剖析

Android系统Surface机制的SurfaceFlinger服务的线程模型分析剖析

Android系统Surface机制的SurfaceFlinger服务的线程模型分析在前面两篇文章中,我们分析了SurfaceFlinger服务的启动过程以及SurfaceFlinger服务初始化硬件帧缓冲区的过程。

从这两个过程可以知道,SurfaceFlinger服务在启动的过程中,一共涉及到了三种类型的线程,它们分别是Binder线程、UI渲染线程和控制台事件监控线程。

在本文中,我们就将详细分SurfaceFlinger服务的线程模型,即上述三种类型的线程是如何运行和交互的。

从一文可以知道,SurfaceFlinger服务是在System进程的主线程中启动的。

System进程的主线程在启动系统的关键服务之前,会先启动一个Binder线程池。

这样运行在System进程中的系统关系服务就可以与其它进程执行Binder进程间通信了。

SurfaceFlinger服务虽然是由System进程的主线程来负责启动的,但是最终它会运行在一个独立的线程中。

我们将这个独立的线程称为UI渲染线程,因为它负责渲染系统的UI。

从一文可以知道,SurfaceFlinger服务的UI渲染线程的启动的时候,会对系统的硬件帧缓冲区进行初始化。

在初始化的过程,又会创建另外一个线程来监控硬件帧缓冲区的睡眠/唤醒状态切换事件。

为了方便描述,我们这个线程称称为控制台事件监控线程。

上述的三种类型的线程的启动顺序,可以通过图1来描述,如下所示:从图1就可以清楚地看到,System进程的主线程负责启动Binder线程池,以及UI渲染线程,而UI渲染线程又负责启动控制台事件监控线程。

在这三种类型的线程中,UI渲染线程是主角,Binder线程和控制台事件监控线程是配角。

Binder线程池是为了让其它进程,例如Android应用程序进程,可以与SurfaceFlinger服务进行Binder进程间通信的,有一部分通信所执行的操作便是让UI渲染线程更新系统的UI。

Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析

Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析

Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析在前面的一系列文章中,我们学习了Android应用程序与SurfaceFlinger服务的关系,以及SurfaceFlinger服务的启动过程、初始化硬件帧缓冲区的过程、线程模型。

SurfaceFlinger服务所做的一切都是为了给Android应用程序提服务的,即为Android应用程序渲染它们的UI。

在本文中,我们就详细分析SurfaceFlinger服务渲染Android应用程序UI的过程。

从前面一文可以知道,SurfaceFlinger服务是通过它的UI渲染线程来将应用程序的UI渲染到硬件帧缓冲区中去的,因此,接下来我们就通过分析SurfaceFlinger服务的UI渲染线程的执行过程来分应用程序UI的渲染过程,这个过程如图1所示。

从图1就可以看出,SurfaceFlinger服务的UI渲染线程的执行过程如下所示:1. 调用SurfaceFlinger类的成员函数handleConsoleEvents来处理控制台事件。

2. 调用SurfaceFlinger类的成员函数handleTransaction来处理系统显示屏以及应用程序窗口的属性变化,例如大小、旋转方向变化等。

3. 调用SurfaceFlinger类的成员函数handlePageFlip来让各个应用程序窗口设置它们当前所要渲染的图形缓冲区。

4. 如果SurfaceFlinger服务在编译的时候指定了USE_COMPOSITION_BYPASS 宏,并且当前需要渲染的应用程序窗口只有一个,那么就会调用SurfaceFlinger类的成员函数handleBypassLayer来直接将这个应用程序窗口的图形缓冲区渲染到硬件帧缓冲区中去,否则的话,就要调用SurfaceFlinger类的成员函数handleRepaint来合成所有的应用程序窗口的图形缓冲区到一个主图形缓冲区中去。

Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析

Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析

Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析在前文中,我们分析了应用程序窗口连接到WindowManagerService服务的过程。

在这个过程中,WindowManagerService服务会为应用程序窗口创建过一个到SurfaceFlinger服务的连接。

有了这个连接之后,WindowManagerService服务就可以为应用程序窗口创建绘图表面了,以便可以用来渲染窗口的UI。

在本文中,我们就详细分析应用程序窗口的绘图表面的创建过程。

从前面和这两个系列的文章可以知道,每一个在C++层实现的应用程序窗口都需要有一个绘图表面,然后才可以将自己的UI表现出来。

这个绘图表面是需要由应用程序进程请求SurfaceFlinger服务来创建的,在SurfaceFlinger服务内部使用一个Layer对象来描述,同时,SurfaceFlinger服务会返回一个实现了ISurface接口的Binder本地对象给应用程序进程,于是,应用程序进程就可以获得一个实现了ISurface接口的Binder代理对象。

有了这个实现了ISurface接口的Binder代理对象之后,在C++层实现的应用程序窗口就可以请求SurfaceFlinger服务分配图形缓冲区以及渲染已经填充好UI数据的图形缓冲区了。

对于在Java层实现的Android应用程序窗口来说,它也需要请求SurfaceFlinger服务为它创建绘图表面,这个绘图表面使用一个Surface对象来描述。

由于在Java层实现的Android应用程序窗口还要接受WindowManagerService服务管理,因此,它的绘图表面的创建流程就会比在C++层实现的应用程序窗口复杂一些。

具体来说,就是在在Java层实现的Android应用程序窗口的绘图表面是通过两个Surface对象来描述,一个是在应用程序进程这一侧创建的,另一个是在WindowManagerService服务这一侧创建的,它们对应于SurfaceFlinger服务这一侧的同一个Layer对象,如图1所示:在应用程序进程这一侧,每一个应用程序窗口,即每一个Activity组件,都有一个关联的Surface对象,这个Surface对象是保在在一个关联的ViewRoot对象的成员变量mSurface中的,如图2所示:图2的类关系图的详细描述可以参考前面一文的图6,这里我们只关注Surface类的实现。

Android中跨历程通讯的4种方式(一)

Android中跨历程通讯的4种方式(一)

Android中跨历程通讯的4种方式(一)长沙Android培训:Android中跨历程通讯的4种方式:由于android系统中应用程序之间不能共享内存。

因此,在不同应用程序之间交互数据(跨进程通讯)就稍微麻烦一些。

在android SDK中提供了4种用于跨进程通讯的方式。

这4种方式正好对应于android系统中4种应用程序组件:Activity、Content Provider、Broadcast和Service。

其中Activity可以跨进程调用其他应用程序的Activity;Content Provider可以跨进程访问其他应用程序中的数据(以Cursor对象形式返回),当然,也可以对其他应用程序的数据进行增、删、改操作;Broadcast可以向android系统中所有应用程序发送广播,而需要跨进程通讯的应用程序可以监听这些广播;Service和Content Provider类似,也可以访问其他应用程序中的数据,但不同的是,Content Provider返回的是Cursor对象,而Service返回的是Java对象,这种可以跨进程通讯的服务叫AIDL服务。

完整示例请参阅本文提供的源代码。

方式一:访问其他应用程序的ActivityActivity既可以在进程内(同一个应用程序)访问,也可以跨进程访问。

如果想在同一个应用程序中访问Activity,需要指定Context对象和Activity的Class对象,代码如下:Intent intent = new Intent(this , Test.class );startActivity(intent);Activity的跨进程访问与进程内访问略有不同。

虽然它们都需要Intent对象,但跨进程访问并不需要指定Context对象和Activity的Class对象,而需要指定的是要访问的Activity所对应的Action(一个字符串)。

有些Activity还需要指定一个Uri(通过Intent构造方法的第2个参数指定)。

Android应用程序组件Content-Provider在应用程序之间共享数据的原理分析

Android应用程序组件Content-Provider在应用程序之间共享数据的原理分析
在Content Provider这一侧,利用在Binder驱动程序为它创建好的这个匿名共享内存文件描述符,在本进程中创建了一个CursorWindow对象。现在,Content Provider开始要从本地中从数据库中查询第三方应用程序想要获取的数据了。Content Provider首先会创建一个SQLiteCursor对象,即SQLite数据库游标对象,它继承了AbstractWindowedCursor类,后者又继承了AbstractCursor类,而AbstractCursor类又实现了CrossProcessCursor和Cursor接口。其中,最重要的是在AbstractWindowedCursor类中,有一个成员变量mWindow,它的类型为CursorWindow,这个成员变量是通过AbstractWindowedCursor的子类SQLiteCursor的setWindow成员函数来设置的。这个SQLiteCursor对象设置好了父类AbstractWindowedCursor类的mWindow成员变量之后,它就具有传输数据的能力了,因为这个mWindow对象内部包含一块匿名共享内存。此外,这个SQLiteCursor对象的内部有两个成员变量,一个是SQLite数据库对象mDatabase,另外一个是SQLite数据库查询对象mQuery。SQLite数据库查询对象mQuery的类型为SQLiteQuery,它继承了SQLiteProgram类,后者又继承了SQLiteClosable类。SQLiteProgram类代表一个数据库存查询计划,它的成员变量mCompiledSql包含了一个已经编译好的SQL查询语句,SQLiteCursor对象就是利用这个编译好的SQL查询语句来获得数据的,但是它并不是马上就去获取数据的,而是等到需要时才去获取。

Android应用程序请求SurfaceFlinger服务创建Surface的过程分析

Android应用程序请求SurfaceFlinger服务创建Surface的过程分析

Android应用程序请求SurfaceFlinger 服务创建Surface的过程分析前面我们已经学习过Android应用程序与SurfaceFlinger服务的连接过程了。

连接上SurfaceFlinger服务之后,Android应用程序就可以请求SurfaceFlinger服务创建Surface。

而当有了Surface后,Android应用程序就可以用来渲染自己的UI了。

在本文中,我们将详细分析Android应用程序请求SurfaceFlinger服务创建Surface的过程。

在讲述Android应用程序请求SurfaceFlinger服务创建Surface之前,我们首先了解一个Surface是由什么组成的。

我们可以将Surface理解为一个绘图表面,Android应用程序负责往这个绘图表面填内容,而SurfaceFlinger服务负责将这个绘图表面的内容取出来,并且渲染在显示屏上。

在SurfaceFlinger服务这一侧,绘图表面使用Layer类来描述,Layer类的实现如图1所示。

Layer类继承了LayerBaseClient类;LayerBaseClient类继承了LayerBase类;LayerBase类继续了RefBase类。

从这些继承关系就可以看出,我们可以通过来引用Layer对象,从而可以自动地维护它们的生命周期。

Layer类内部的成员变量mUserClientRef指向了一个ClientRef对象,这个ClientRef 对象内部有一个成员变量mControlBlock,它指向了一个SharedBufferServer对象。

从前面一文可以知道,SharedBufferServer类是用来在SurfaceFlinger服务这一侧描述一个UI元数据缓冲区堆栈的,即在SurfaceFlinger服务中,每一个绘图表面,即一个Layer对象,都关联有一个UI元数据缓冲区堆栈。

LayerBaseClient类内部有一个类型为LayerBaseClient::Surface的弱指针,它引用了一个Layer::SurfaceLayer对象。

Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析

Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析

Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析在前两文中,我们分析了Activity组件的窗口对象和视图对象的创建过程。

Activity组件在其窗口对象和视图对象创建完成之后,就会请求与WindowManagerService建立一个连接,即请求WindowManagerService为其增加一个WindowState对象,用来描述它的窗口状态。

在本文中,我们就详细分析Activity组件与WindowManagerService的连接过程。

我们从两方面来看Activity组件与WindowManagerService服务之间的连接。

一方面是从Activity组件到WindowManagerService服务的连接,另一方面是从WindowManagerService服务到Activity组件的连接。

从Activity组件到WindowManagerService服务的连接是以Activity组件所在的应用程序进程为单位来进行的。

当一个应用程序进程在启动第一个Activity组件的时候,它便会打开一个到WindowManagerService服务的连接,这个连接以应用程序进程从WindowManagerService服务处获得一个实现了IWindowSession接口的Session代理对象来标志。

从WindowManagerService服务到Activity组件的连接是以Activity组件为单位来进行的。

在应用程序进程这一侧,每一个Activity组件都关联一个实现了IWindow接口的W对象,这个W对象在Activity组件的视图对象创建完成之后,就会通过前面所获得一个Session代理对象来传递给WindowManagerService服务,而WindowManagerService服务接收到这个W对象之后,就会在内部创建一个WindowState对象来描述与该W对象所关联的Activity组件的窗口状态,并且以后就通过这个W对象来控制对应的Activity组件的窗口状态。

Android应用程序请求SurfaceFlinger服务渲染Surface的过程分析

Android应用程序请求SurfaceFlinger服务渲染Surface的过程分析

Android应用程序请求SurfaceFlinger 服务渲染Surface的过程分析在前面一篇文章中,我们分析了Android应用程序请求SurfaceFlinger服务创建Surface的过程。

有了Surface之后,Android应用程序就可以在上面绘制自己的UI了,接着再请求SurfaceFlinger服务将这个已经绘制好了UI的Surface渲染到设备显示屏上去。

在本文中,我们就将详细分析Android应用程序请求SurfaceFlinger服务渲染Surface的过程。

Android应用程序在请求SurfaceFlinger服务渲染一个Surface之前,首先要将该Surface作为当前活动的绘图上下文,以便可以使用OpengGL库或者其它库的API来在上面绘制UI,我们以Android系统的开机动画应用程序bootanim为例,来说明这个问题。

从前面一文可以知道,Android系统的开机动画应用程序bootanim是在BootAnimation类的成员函数readyToRun中请求SurfaceFlinger服务创建Surface的。

这个Surface创建完成之后,就会被设置为当前活动的绘图上下文,如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片status_t BootAnimation::readyToRun() {......// create the native surfacesp<SurfaceControl> control = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);......sp<Surface> s = control->getSurface();......// initialize opengl and eglconst EGLint attribs[] = {EGL_DEPTH_SIZE, 0,EGL_NONE};......EGLConfig config;EGLSurface surface;EGLContext context;EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);eglInitialize(display, 0, 0);EGLUtils::selectConfigForNativeWindow(display, attribs, s.get(), &config);surface = eglCreateWindowSurface(display, config, s.get(), NULL);context = eglCreateContext(display, config, NULL, NULL);......if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)return NO_INIT;......}BootAnimation类的成员函数readyToRun首先调用eglGetDisplay和eglInitialize函数来获得和初始化OpengGL库的默认显示屏,接着再调用EGLUtils::selectConfigForNativeWindow函数来获得前面所创建的一个Surface(由sp<Surface>指针s来描述)的配置信息。

如何实现Android应用程序之间数据共享的

如何实现Android应用程序之间数据共享的

如何实现Android应用程序之间数据共享的一个应用程序可以将自己的数据完全暴露出去,外界更本看不到,也不用看到这个应用程序暴露的数据是如何存储的,或者是使用数据库还是使用文件,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和这个程序里的数据打交道,例如:添加(insert)、删除(delete)、查询(query)、修改(update),当然需要一定的权限才可以。

如何将应用程序的数据暴露出去? Android提供了ContentProvider,一个程序可以通过实现一个Content provider的抽象接口将自己的数据完全暴露出去,而且Content providers 是以类似数据库中表的方式将数据暴露。

Content providers存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。

要想使应用程序的数据公开化,可通过2种方法:创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中,前提是有相同数据类型并且有写入Content provider的权限。

如何通过一套标准及统一的接口获取其他应用程序暴露的数据?Android提供了ContentResolver,外界的程序可以通过ContentResolver接口访问ContentProvider提供的数据。

当前篇主要说明,如何获取其它应用程序共享的数据,比如获取Android 手机电话薄中的信息。

什么是URI?在学习如何获取ContentResolver前,有个名词是必须了解的:URI。

URI是网络资源的定义,在Android中赋予其更广阔的含义,先看个例子,如下:将其分为A,B,C,D 4个部分:A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的;B:URI的标识,它定义了是哪个Content Provider提供这些数据。

Android之Surface

Android之Surface

Android之Surface⼀、Surface是什么 Handle onto a raw buffer that is being managed by the screen compositor. ⼤概意思是处理由屏幕合成器管理的原理缓存区。

⼆、Surface实现原理 在Surface类⾥有⼀个Canvas对象,在Canvas⾥有⼀个Bitmap,Bitmap是真正的画布。

Bitmap是什么 Bitmap缩写是BMP,是⼀种存储像素的数据结构。

三、Surface跨进程间传递 源码:frameworks/base/core/java/android/view/Surface.java/*** Handle onto a raw buffer that is being managed by the screen compositor.** <p>A Surface is generally created by or from a consumer of image buffers (such as a* {@link android.graphics.SurfaceTexture}, {@link android.media.MediaRecorder}, or* {@link android.renderscript.Allocation}), and is handed to some kind of producer (such as* {@link android.opengl.EGL14#eglCreateWindowSurface(android.opengl.EGLDisplay,android.opengl.EGLConfig,ng.Object,int[],int) OpenGL},* {@link android.media.MediaPlayer#setSurface MediaPlayer}, or* {@link android.hardware.camera2.CameraDevice#createCaptureSession CameraDevice}) to draw* into.</p>** <p><strong>Note:</strong> A Surface acts like a* {@link ng.ref.WeakReference weak reference} to the consumer it is associated with. By* itself it will not keep its parent consumer from being reclaimed.</p>*/public class Surface implements Parcelable {……} Surface继承⾃Parcelable,Parcelable是⼀个序列化接⼝,将对象转化为⼆进制流(⼆进制序列)的过程。

Android如何在Activity和Service之间传递数据-走自己的路-CSDN博客

Android如何在Activity和Service之间传递数据-走自己的路-CSDN博客

Android如何在Activity和Service之间传递数据-走自己的路-CSDN博客Android如何在Activity和Service之间传递数据收藏一个Android程序可以由多个Activity和Servier组成,在这些程序组件之间传递数据的方法有以下几种,每种方法都有其特定的使用途径。

1、原始数据类型:在Activity/Servier之间传递临时性的原始数据,可以使用Intent 的putExtras方法来传递数据。

若传递的数据需要长久保存,则使用SharedPreference类来完成。

2、传递对象。

当在Activity/Servier之间传递不需要长久保存的对象时,可以使用以下几种途径:(1)通过Application类,每个Android应用程序都有一个Application类。

当你在程序的AndroidManifest.xml中给Application设定一个名字时,你的程序中就必须有一个Application 的子类。

这个Application子类会被Android自动实例化,并且是一个全家性的类,它的生命周期和程序的生命周期相同,你可以把一些全局性的对象保存在Application类中。

Application类可以通过getApplication()获得。

(2 通过HashMap of WeakReferences传递对象。

当一个Activity需要向另外一个Activity传递对象时,可以使用一个关键字把对象存在一个 HashMap中,并把这个关键字通过Internt的Extras发给目标Activity,目标Activity接到该关键字后使用该关键字把对象冲HashMap中取出。

在Activity/Service之间传递需要长久保存的对象时,可以使用以下的方式:Application PreferencesFilescontentProvidersSQLite DB。

「Android」SurfaceFlinger分析

「Android」SurfaceFlinger分析

「Android」SurfaceFlinger分析本篇针对surfaceFlinger模块进⾏分析,⽬录如下:1、SurfaceFlinger功能 1.1、BufferQueue原理(native/libs/gui模块) 1.2 layer显⽰内存分配(native/libs/ui模块) 1.3、surfaceFlinger处理(native/.../surfaceFlinger模块)2、⼯程代码解析: 2.1、surfaceFlinger启动过程 2.2、surfaceFlinger事务处理3、总结(处理流程、交互模块)***********************************************************×*********************************×*******1、SurfaceFlinger功能:surfaceflinger作⽤是接受多个来源的图形显⽰数据,将他们合成,然后发送到显⽰设备。

⽐如打开应⽤,常见的有三层显⽰,顶部的statusbar底部或者侧⾯的导航栏以及应⽤的界⾯,每个层是单独更新和渲染,这些界⾯都是有surfaceflinger合成⼀个刷新到硬件显⽰。

在显⽰过程中使⽤到了bufferqueue,surfaceflinger作为consumer⽅,⽐如windowmanager管理的surface作为⽣产⽅产⽣页⾯,交由surfaceflinger进⾏合成。

1.1、BufferQueue原理(和SF交互)bufferqueue分为⽣产者和消费者⽐如应⽤通过windowsmanager分配⼀个surface,需要分配(dequeueBuffer)显⽰空间在上⾯进⾏绘图,在图形绘制完成后需要推送(queueBuffer)到surfaceflinger进⾏合成显⽰。

surfaceflinger作为消费者,通过acquireBuffer()得到⼀个要合成的图形,在合成完毕后再releaseBuffer()将图形释放。

Android应用程序与SurfaceFlinger服务的连接过程分析

Android应用程序与SurfaceFlinger服务的连接过程分析

Android应用程序与SurfaceFlinger服务的连接过程分析前文在描述Android应用程序和SurfaceFlinger服务的关系时提到,每一个有UI的Android 应用程序都需要与SurfaceFlinger服务建立一个连接,以便可以通过这个连接来请求SurfaceFlinger服务为它创建和渲染Surface。

在本文中,我们将以Android系统的开机动画应用程序为例,详细描述Android应用程序是如何与SurfaceFlinger服务建立连接的。

Android系统的开机动画是由应用程序bootanimation来实现的,它位于/system/bin 目录下,它的具体实现可以参考一文。

为什么要选择Android系统的开机动画来分析Android应用程序与SurfaceFlinger服务的连接过程呢?首先,负责实现开机动画的应用程序bootanimation也是一个Android应用程序,只不过它是使用C++语言来开发的;其次,应用程序bootanimation是与UI相关的,即它与使用Java语言来开发的标准Android应用程序一样,都需要使用SurfaceFlinger服务来创建和渲染自己的Surface,即开机动画;第三,由于应用程序bootanimation不涉及用户输入,即不需要与用户进行交互(触摸屏、键盘等),因此它能够以最简洁的方式来体现Android应用程序与SurfaceFlinger服务的关系。

从前面一文可以知道,Android系统的开机动画是主要一个BootAnimation对象来实现,这个BootAnimation对象在构造的时候,会在内部创建一个SurfaceComposerClient 对象来负责创建一个到SurfaceFlinger服务的连接。

BootAnimation类的构造函数实现在文件frameworks/base/cmds/bootanimation/BootAnimation.cpp中,如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片BootAnimation::BootAnimation() : Thread(false){mSession = new SurfaceComposerClient();}mSession是BootAnimation类的成员变量,它是一个类型为SurfaceComposerClient 的强指针,即sp<SurfaceComposerClient>。

Android在两个进程之间共享SurfaceTexture

Android在两个进程之间共享SurfaceTexture

Android在两个进程之间共享SurfaceTexture是否可以在两个进程之间共享SurfaceTexture,例如Activity和Service?我想用T extureView创建一个Activity,并从一个单独的Service更新它的SurfaceT exture.到目前为止,我正在创建一个带有生成的OpenGL纹理的SurfaceTexture(通过glGenTextures),然后我将这个表面纹理设置为我的TextureView:mSurfaceTexture = new SurfaceT exture(texture_id);mTextureView.setSurfaceTexture(mSurfaceTexture);在活动上显示此SurfaceTexture的相机预览正常工作:mCamera = Camera.open();mCamera.setPreviewTexture(mTextureView.getSurfaceT extur e());mCamera.startPreview();我想做同样的事情,但是从一个单独的服务,将texture_id传递给它,类似于:mCamera = Camera.open();mCamera.setPreviewTexture(new SurfaceTexture(texture_id));mCamera.startPreview();原因是我有一个单独的进程调用私有api,需要SurfaceTexture来传输一些内容,并且可以通过应用程序中的aidl访问此进程.谢谢解决方法:系统支持执行您想要的操作,但我不知道是否可以使用当前的公共API.一些背景,以确保我们在同一页…Surface是生产者–消费者对的生产者.使用SurfaceTexture,应用程序可以访问两端.渲染到SurfaceT exture曲面的任何内容都将转换为OpenGL ES“外部”纹理.媒体和显示API的工作方式是让消费者创建对,然后将Surface交给应用程序.这就是为什么,如果你创建一个SurfaceView,你不能使用Surface,直到surfaceCreated()回调触发–BufferQueue对象由系统图形合成器(SurfaceFlinger)创建,生产者端通过Binder IPC传递给你的应用.对于MediaCodec编码器的Surface输入也是如此,它们由mediaserver进程创建.您可以将SurfaceView或SurfaceTexture获得的Surface传递给产生输出的东西,例如Camera preview或MediaCodec解码器.在引擎盖下,这些通过IPC传递到mediaserver过程.生成帧时,图形缓冲区通过引用传递给使用者. SurfaceFlinger显示从SurfaceView获取的帧,SurfaceT exture只是将它们转换为纹理.所以你想要做的是在app中创建一个SurfaceTexture,为它构造一个Surface,并将Surface传递给你的服务.您的服务会生成帧并将它们写入Surface,这会将它们通过IPC发送到您应用中的SurfaceTexture 消费者,这会将它们转换为GLES纹理.我没有尝试通过AIDL传递Surface,所以我不知道它是否真的有效.在进程之间传递纹理ID将不起作用.如果在创建第二个上下文时将第一个上下文作为参数传递,则可以从两个不同的EGLContex中访问一个纹理,但我不认为这可能会跨进程工作.。

【转】Android平台——Surfaceflinger机制

【转】Android平台——Surfaceflinger机制

【转】Android平台——Surfaceflinger机制Android平台——Surfaceflinger机制看到有人在blog上留言,说希望看到Surfaceflinger这一部分的内容,最近没有时间写blog,只能先暂时掐断Binder机制,写这部分的内容。

同样从几个月前的工作笔记中摘录下来。

也没有细细去回顾一下,全当交个差。

忙过了这段,我一定会回过头来整理的首先声明,我们忽略Binder机制的细节。

从头开始查找数据的流向,也就是SurfaceFlinger类这一层从上层接受数据的过程,先看一组继承关系以便于分析(这个总略图将帮你看清数据流向):MSN的图片太不清楚了抑郁!,大家凑和看吧!!这里LayerBuffer的创建是在SurfaceFlinger中由SurfaceFlinger 的友员类BClient调用createSurface函数new出LayBuffer对象。

数据流向过程,以opencore解码举例:opencore中调用ISuface的postBuff,实际ISurface的继承类BpSurface中的postBuffer被调用,通过Binder机制向同样是ISurface的继承类的BnSurface请求服务(通过发送POST_BUFFER命令):virtual void BpSurface ::postBuffer(ssize_t offset){……………………………………………….remote()->transact(POST_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);}BnSurface响应相应命令,同样调用postBuffer函数:case POST_BUFFER: {…………………………….postBuffer(offset);…………………………….}实际将会调用BnSurface的继承类Surface的postBuffer函数(class Surface : public BnSurface),Surface是LayBaseClient的嵌入类,而Surface类的postBuffer函数未实现,这会导致最终调用Surface类的继承类SurfaceBuffer的postBuffer函数(class SurfaceBuffer : public LayerBaseClient::Surface):void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset){……………………………………………..owner->postBuffer(offset);}SurfaceBuffer类是LayBaseClient的继承类LayerBuffer的嵌入类,SurfaceBuffer的postBuffer最终会调用LayerBuffer的postBuffer函数:void LayerBuffer::postBuffer(ssize_t offset){…………………………………………….sp<Buffer> buffer;if (heap != 0) {buffer = new Buffer(heap, offset, w, h, hs, vs, f);if (buffer->getStatus() != NO_ERROR)buffer.clear();setBuffer(buffer); //这个函数将会置mBuffer指针invalidate();}}在此函数中将会创建Buffer类用来存储数据,LayerBuffer类中的mBuffer指针会指向这个数据区由BClient利用。

Android—Service与Activity的交互

Android—Service与Activity的交互

Android—Service与Activity的交互 service—Android的四⼤组件之⼀。

⼈称“后台服务”指其本⾝的运⾏并不依赖于⽤户可视的UI界⾯实际开发中我们经常需要service和activity之间可以相互传递数据维持程序的运⾏。

先了解Service的⽣命周期吧。

新建⼀个类继Service:package com.example.myservicedemo.service;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;/*** 服务类(需要在项⽬清单⽂件中注册服务)** @author lenovo**/public class MyService extends Service {@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}/*** 服务创建的时候调⽤*/@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();System.out.println("=========onCreate======");}/*** 服务启动的时候调⽤*/@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubSystem.out.println("=========onStartCommand======");return super.onStartCommand(intent, flags, startId);}/*** 服务销毁的时候调⽤*/@Overridepublic void onDestroy() {// TODO Auto-generated method stubSystem.out.println("=========onDestroy======");super.onDestroy();}}新建以上类并继承Service后只会重写onBind()⽅法,其他⽅法是我⼿动⼿写,为了弄清楚Service的⽣命周期 MainActivity中(设置两个按钮⽤来开始和停⽌服务):package com.example.myservicedemo.ui;import com.example.myservicedemo.R;import com.example.myservicedemo.service.MyService;import com.example.myservicedemo.service.MyService.DownLoadBinder;import android.app.Activity;import ponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity implements OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);Button btn_start = (Button) findViewById(R.id.btn_start);Button btn_stop = (Button) findViewById(R.id.btn_stop);btn_start.setOnClickListener(this);btn_stop.setOnClickListener(this);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubint id = v.getId();switch (id) {/** 开启服务点击事件*/case R.id.btn_start:Intent startIntent = new Intent(this, MyService.class);startService(startIntent);break;/** 停⽌服务点击事件*/case R.id.btn_stop:Intent stopIntent = new Intent(this, MyService.class);stopService(stopIntent);break;default:break;}}} 切记android中的服务是需要在项⽬清单⽂件中注册的(AndroidStudio可以⾃动,eclipse需要⼿动添加):<service android:name="服务类坐所在的包名.MyService"></service>此时运⾏程序,点击开启服务时候输出是下图:(我输出多次onStartCommand()是因为我连续点击了多次开启服务按钮)上图可以看出服务第⼀次开启时先是调⽤了onCreate()⽅法和onStartCommand()⽅法,多次点击开始服务时只调⽤了onStartCommand()⽅法so:onCreate()⽅法是服务创建的时候调⽤的~onStartCommand()⽅法在每次启动服务的时候都会调⽤~onDestory()⽅法在停⽌服务时候会调⽤~点击停⽌服务后,输出如图:启动服务还有⼀种⽅式是bindService();此时的MyService类要做改变:package com.example.myservicedemo.service;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;/*** 服务类(需要在项⽬清单⽂件中注册服务)** @author lenovo**/public class MyService extends Service {private DownLoadBinder downLoadBinder=new DownLoadBinder();@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubSystem.out.println("=====onBind=====");return downLoadBinder;}/*** 内部类继承Binder* @author lenovo**/public class DownLoadBinder extends Binder{public void startDownLoad(){System.out.println("=====startDownLoad()=====");}public void getProgress(){System.out.println("=====getProgress()=====");}}/*** 服务创建的时候调⽤*/@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();System.out.println("=========onCreate======");}/*** 服务启动的时候调⽤*/@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubSystem.out.println("=========onStartCommand======");return super.onStartCommand(intent, flags, startId);}/*** 服务销毁的时候调⽤*/@Overridepublic void onDestroy() {// TODO Auto-generated method stubSystem.out.println("=========onDestroy======");super.onDestroy();}} 以上的代码和第⼀次相⽐,⼀是多了⼀个内部类DownLoadBinder继承IBinder并且声明了两个⽅法,⼆是将onBind⽅法的返回值改为了DownLoadBinder类型的变量activity bindService⽅法启动服务时候⼀般是需要传递数据的,核⼼就在onBind()⽅法中,往下看 MainActivity中加两个按钮:绑定服务和取消绑定服务package com.example.myservicedemo.ui;import com.example.myservicedemo.R;import com.example.myservicedemo.service.MyService;import com.example.myservicedemo.service.MyService.DownLoadBinder;import android.app.Activity;import ponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity implements OnClickListener {private MyService.DownLoadBinder downLoadBinder;private MyService myService; //我们⾃⼰的service@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);Button btn_start = (Button) findViewById(R.id.btn_start);Button btn_stop = (Button) findViewById(R.id.btn_stop);Button btn_bind = (Button) findViewById(R.id.btn_bind);Button btn_unbind = (Button) findViewById(R.id.btn_unbind);btn_start.setOnClickListener(this);btn_stop.setOnClickListener(this);btn_bind.setOnClickListener(this);btn_unbind.setOnClickListener(this);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubint id = v.getId();switch (id) {/** 开启服务点击事件*/case R.id.btn_start:Intent startIntent = new Intent(this, MyService.class);startService(startIntent);break;/** 停⽌服务点击事件*/case R.id.btn_stop:Intent stopIntent = new Intent(this, MyService.class);stopService(stopIntent);break;/** 绑定服务点击事件*/case R.id.btn_bind:Intent bindIntent = new Intent(this, MyService.class);bindService(bindIntent, connection, BIND_AUTO_CREATE);break;/** 解除绑定服务点击事件case R.id.btn_unbind:unbindService(connection);break;default:break;}}private ServiceConnection connection=new ServiceConnection() {/*** 服务解除绑定时候调⽤*/@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}/*** 绑定服务的时候调⽤*/@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stub//myService=((DownLoadBinder) service).downLoadBinder=(DownLoadBinder) service;/** 调⽤DownLoadBinder的⽅法实现参数的传递*/downLoadBinder.startDownLoad();downLoadBinder.getProgress();}};} 运⾏后点击绑定服务后输出如下:说明成功绑定了服务且传递了数据,点击解除绑定服务时候ondestory()⽅法输出不过这种⽅法好像只能传递⼀次数据,,,,不爽,,,,⽐如后台在实时更新东西,activity需要实时获取呢查找资料⼤多是以下⼏种⽅式:1.使⽤接⼝回调⽅式,activity实现相应的接⼝,service通过接⼝进⾏回调,⽐较灵活2.使⽤⼴播这篇博客主要介绍第⼀种⽅法,为什么不介绍第⼆种——不愿意介绍,不喜欢。

AndroidActivity与Service进行数据交互详解

AndroidActivity与Service进行数据交互详解

AndroidActivity与Service进⾏数据交互详解①从设计的⾓度来讲:Android的Activity的设计与Web页⾯⾮常类似,从页⾯的跳转通过连接,以及从页⾯的定位通过URL,从每个页⾯的独⽴封装等⽅⾯都可以看出来,它主要负责与⽤户进⾏交互。

Service则是在后台运⾏,默默地为⽤户提供功能,进⾏调度和统筹。

如果⼀棵树的地上部分是Activity的话,它庞⼤的根须就是Service。

Android的服务组件没有运⾏在独⽴的进程或线程中,它和其他的组件⼀样也在应⽤的主线程中运⾏,如果服务组件执⾏⽐较耗时的操作就会导致主线程阻塞或者假死,从⽽⽆法响应⽤户的操作。

因此,耗时的操作不要放在UI线程中,因为UI 5S,⼴播10s就阻塞了,会引发ANR。

②从使⽤的⾓度来讲:Service不仅可以给Activity建⽴双向连接,为Activity提供数据和功能⽀持,也可以单向接受Intent的请求,进⾏数据的分析处理和功能调度。

③从扮演的⾓⾊来讲:Activity的功能⽐较单⼀,主要就是显⽰应⽤所具有的⼀些功能,帮助⽤户与应⽤进⾏交互,像⼀个⼈的脸。

⽽Service可能扮演功能调度者也能扮演功能提供者,从触发器收集信息进⾏分析和处理,然后更新界⾯,修改数据或进⾏其他操作时是⼀个功能调度者,从输⼊法的选择考虑Service扮演的就是⼀个功能提供者。

View组件是Android中⽤户能够实实在在看到的部分,如按钮,输⼊框等就是继承⾃这个类,View只有装⼊Activity这样的容器中才有意义,⽽反过来Activity装⼊了这些View后才能够成功完成与⽤户交互的任务,但是Service不需要这些花哨的东西,只需要默默地等待事件发⽣或者听候差遣。

Android启动Service有两种⽅法,⼀种是startService,⼀种是bindService。

⽣命周期如下:执⾏startService时,调⽤者如果没有stopService,Service会⼀直在后台运⾏。

Android系统Surface机制的SurfaceFlinger服务的启动过程分析

Android系统Surface机制的SurfaceFlinger服务的启动过程分析
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exiting thread pool.\n");
}
return NO_ERROR;
}
函数首先获得System进程中的一个ProcessState单例,并且保存在变量proc中,后面会通过调用它的成员函数supportsProcesses来判
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
......
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
从前面一文可以知道,System进程是由Zygote进程启动的,并且是以Java层的SystemServer类的静态成员函数main为入口函数的。因此,接下来我们就从SystemServer类的静态成员函数main开始,分析SurfaceFlinger服务的启动过程,如图1所示。
SurfaceFlinger服务的启动过程可以划分为8个步骤,接下来我们就详细分析每一个步骤。
的UI渲染线程启动起来,等到后面再启动。
SurfaceFlinger服务在创建的过程中,会调用SurfaceFlinger类的成员函数init来执行初始化的操作,接下来,我们就继续分析它的实
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析在前面一篇文章中,我们分析了Android应用程序与SurfaceFlinger服务的连接过程。

Android应用程序成功连接上SurfaceFlinger服务之后,还需要一块匿名共享内存来和SurfaceFlinger服务共享它的UI元数据,以便使得SurfaceFlinger服务可以正确地为它创建以及渲染Surface。

在本文中,我们将详细地分析这块用来保存UI元数据的匿名共享内存的创建过程。

在一文中提到,用来保存Android应用程序的UI元数据的匿名共享内存最终是被结构化为一个SharedClient对象来访问的。

每一个与UI有关的Android应用程序进程有且仅有一个SharedClient对象,而且这些SharedClient对象是由Android应用程序请求SurfaceFlinger服务创建的:Android应用程序首先获得SurfaceFlinger服务的一个Binder代理接口,然后再通过这个代理接口得到另外一个类型为UserClient的Binder代理接口,最后就可以通过后一个Binder代理接口来获得一个SharedClient对象。

由于每一个与UI有关的Android应用程序进程有且仅有一个SharedClient对象,因此,Android系统就通过一个单例模式的类来专负责创建和管理这个SharedClient对象。

这个类的名称为SurfaceClient,定义在frameworks/base/libs/surfaceflinger_client/Surface.cpp 文件中,如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片class SurfaceClient : public Singleton<SurfaceClient>{// all these attributes are constantssp<ISurfaceComposer> mComposerService;sp<ISurfaceComposerClient> mClient;status_t mStatus;SharedClient* mControl;sp<IMemoryHeap> mControlMemory;SurfaceClient(): Singleton<SurfaceClient>(), mStatus(NO_INIT){sp<ISurfaceComposer> sf(ComposerService::getComposerService());mComposerService = sf;mClient = sf->createClientConnection();if (mClient != NULL) {mControlMemory = mClient->getControlBlock();if (mControlMemory != NULL) {mControl = static_cast<SharedClient *>(mControlMemory->getBase());if (mControl) {mStatus = NO_ERROR;}}}}friend class Singleton<SurfaceClient>;public:status_t initCheck() const {return mStatus;}SharedClient* getSharedClient() const {return mControl;}ssize_t getTokenForSurface(const sp<ISurface>& sur) const {// TODO: we could cache a few tokens here to avoid an IPCreturn mClient->getTokenForSurface(sur);}void signalServer() const {mComposerService->signal();}};当SurfaceClient类的静态成员函数getInstance第一次被调用的时候,系统就会在对应的应用程序进程中创建一个SurfaceClient对象,即会调用SurfaceClient类的构造函数。

SurfaceClient类的构造函数首先会调用ComposerService类的静态成员函数getComposerService来获得一个SurfaceFlinger服务的代理接口,并且保存在SurfaceClient 类的成员变量mComposerService中,以便以后可以使用。

ComposerService类的静态成员函数getComposerService在前面一文中已经分析过了,这里不再详述。

有了SurfaceFlinger 服务的代理接口sf之后,SurfaceClient类的构造函数接着就可以调用它的成员函数createClientConnection来获得一个类型为UserClient的Binder代理接口,这个Binder代理接口实现了ISurfaceComposerClient接口,因此,我们可以将它保存在SurfaceClient类的成员变量mClient中。

最后,SurfaceClient类的构造函数就调用前面获得的类型为ISurfaceComposerClient的Binder代理接口mClient的成员函数getControlBlock来获得一块用来描述应用程序UI元数据的匿名共享内存mControlMemory ,并且将这些匿名共享内存强制转化为一个SharedClient对象mControl,以便后面可以方便地访问UI元数据。

以上就是Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程的总体描述,接下来我们再详细分析每一步的实现。

现在,我们继续分析一下SurfaceClient类的其余成员函数的实现:1. 成员函数initCheck用来检查一个Android应用程序进程是否已经成功地请求SurfaceFlinger服务创建了一块用来描述UI元数据的SharedClient对象了。

2. 成员函数getSharedClient用来返回用来描述UI元数据的SharedClient对象mControl。

3. 成员函数getTokenForSurface用来返回由参数sur所描述的一个Surface的Token 值。

这个Token值由SurfaceFlinger服务来创建和管理,并且可以通过前面所获得的类型为UserClient的Binder代理接口mClient的成员函数getTokenSurface来获得。

4. 成员函数signalServer用来通知SurfaceFlinger服务更新Android应用程序UI,这是通过调用SurfaceFlinger服务的代理接口mComposerService的成员函数signal来实现的,实际上就是向SurfaceFlinger服务发送一个信号,以便可以将它唤醒起来更新UI。

介绍完成SurfaceClient类的实现之后,我们还需要了解一下两个类的实现,即UserClient类和SharedClient类的实现,以便可以帮助我们了解用来保存Android应用程序的UI元数据的匿名共享内存的创建过程,以及帮助后面两篇文章对Surface的创建和渲染过程的分析。

接下来,我们就首先分析UserClient类的实现,接着再分析SharedClient类的实现。

在一文的图2中,我们介绍了用来连接Android应用程序和SurfaceFlinger服务的Client类,而UserClient类和Client类是类似的,它们都实现了相同的接口,只不过是侧重点有所不同。

一文的图2中的Client类替换成UserClient类,就可以得到UserClient 类的实现结构图,如图1所示:UserClient类与Client类最重要的区别是,前者实现了ISurfaceComposerClient接口的成员函数getControlBlock,而后者实现了ISurfaceComposerClient接口的成员函数createSurface。

后面我们就会分析UserClient类是如何实现ISurfaceComposerClient接口的成员函数getControlBlock的。

UserClient类的实现暂时就介绍到这里,接下来我们来看SharedClient类的实现。

为了方便描述,我们把一文的图4和图5贴出来,如以下图2和图3所示:每一个SharedClient对象包含了至多31个SharedBufferStack,而每一个SharedBufferStack 都对应一个Android应用程序进程中的一个Surface。

SharedClient类定义在文件frameworks/base/include/private/surfaceflinger/SharedBufferStack.h 文件中,如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片class SharedClient{public:SharedClient();~SharedClient();......private:......SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ];};它有一个大小为SharedBufferStack::NUM_LAYERS_MAX的SharedBufferStack数组。

SharedBufferStack::NUM_LAYERS_MAX的值等于31,定义在SharedBufferStack类中。

SharedBufferStack类同样是定义在文件frameworks/base/include/private/surfaceflinger/SharedBufferStack.h 文件中,如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片class SharedBufferStack{......public:// When changing these values, the COMPILE_TIME_ASSERT at the end of this// file need to be updated.static const unsigned int NUM_LAYERS_MAX = 31;static const unsigned int NUM_BUFFER_MAX = 16;static const unsigned int NUM_BUFFER_MIN = 2;static const unsigned int NUM_DISPLAY_MAX = 4;......struct SmallRect {uint16_t l, t, r, b;};struct FlatRegion {static const unsigned int NUM_RECT_MAX = 5;uint32_t count;SmallRect rects[NUM_RECT_MAX];};struct BufferData {FlatRegion dirtyRegion;SmallRect crop;uint8_t transform;uint8_t reserved[3];};SharedBufferStack();......status_t setDirtyRegion(int buffer, const Region& reg);status_t setCrop(int buffer, const Rect& reg);status_t setTransform(int buffer, uint8_t transform);Region getDirtyRegion(int buffer) const;Rect getCrop(int ffer) const;uint32_t getTransform(int buffer) const;// these attributes are part of the conditions/updatesvolatile int32_t head; // server's current front buffervolatile int32_t available; // number of dequeue-able buffersvolatile int32_t queued; // number of buffers waiting for post......// not part of the conditions......volatile int8_t index[NUM_BUFFER_MAX];......int8_t headBuf; // last retired buffer......BufferData buffers[NUM_BUFFER_MAX];};下面我们简要地对SharedBufferStack类进行分析。

相关文档
最新文档