本篇文章根据前面的分析来实际操作画一个窗口,使用纯native API来实现,这里的native API并非ndk,而是native层函数,需要在AOSP编译环境下进行。 首先在 接着来看看 我们的代码就按上面步骤来写, 上面的代码基本上是按照画窗口的流程来实现的,看下上面 会调用 这个函数指针是在 这里面有很多函数,根据传递过来的参数调用不同的 画一个窗口有很多信息必须设置,在之前分析的 编译测试程序:mmm frameworks/native/libs/gui/drawWindowTest/ 运行这个测试程序:adb shell /system/bin/drawWindow/frameworks/native/libs/gui/目录下创建drawWindowTest测试目录,drawWindowTest目录中创建Android.bp和DrawWindowTest.cpp:
 
 Android.bp:cc_binary {     name: "drawWindow",     srcs: ["DrawWindowTest.cpp"],     shared_libs: [ "liblog",         "libbinder",         "libgui",         "libui",         "libutils",     ], } DrawWindowTest.cpp怎么写,前面几篇文章的分析我们大致了解了画一个窗口的流程:
SurfaceFlinger进程建立连接Surface对应SurfaceFlinger进程LayerSurface,还需要将Surface连接到BufferQueueSurface的各种数据,如宽高,格式,Z-order,位置,缩放等dequeueBuffer获取bufferqueueBuffer将buffer送到SurfaceFlinger合成DrawWindowTest.cpp源码如下:#include <binder/ProcessState.h> #include <binder/IPCThreadState.h> #include <system/window.h> #include <ui/GraphicBuffer.h> #include <ui/Fence.h> #include <utils/Log.h> #include <utils/RefBase.h> #include <gui/SurfaceControl.h> #include <gui/SurfaceComposerClient.h> #include <binder/IBinder.h> #include <ui/DisplayInfo.h> #include <gui/Surface.h> using namespace android; //状态值 status_t err;  sp<SurfaceComposerClient> mSurfaceComposerClient;  sp<SurfaceControl> mSurfaceControl; //屏幕宽高 int mWidth,mHeight; //GraphicBuffer的父类ANativeWindowBuffer ANativeWindowBuffer *mNativeBuffer = nullptr; //连接SurfaceFlinger void connectSurfaceFlinger(); //获取Surface sp<ANativeWindow> getSurface(); //连接BufferQueue void connectBufferQueue(ANativeWindow *surface); //设置Transaction void setBufferTransaction(); //设置其他信息 void setBuffer(ANativeWindow *surface); int main() {     sp<ProcessState> proc(ProcessState::self());     ProcessState::self()->startThreadPool(); //连接SurfaceFlinger connectSurfaceFlinger(); //获取surface     ANativeWindow *surface = getSurface().get(); //surface连接bufferqueue connectBufferQueue(surface); //设置Transaction setBufferTransaction(); //设置其他信息 setBuffer(surface); int fenceFD= -1; //申请buffer     err = surface->dequeueBuffer(surface, &mNativeBuffer, &fenceFD); if (err != NO_ERROR) { ALOGE("dequeueBuffer err...."); } //通过Fence确认申请的buffer是否完全被上一个使用者使用完         sp<Fence> fence(new Fence(fenceFD)); //等待收到releaseFence int waitResult = fence->waitForever("dequeueBuffer_EmptyNative"); if (waitResult != OK) { ALOGE("Fence wait err...."); } //ANativeWindowBuffer转GraphicBuffer         sp<GraphicBuffer> buff(GraphicBuffer::from(mNativeBuffer)); //buffer数据 uint8_t *data = NULL; //通过lock先锁住buffer         err = buff->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&data)); if (err != NO_ERROR) { ALOGE("lock buffer err...."); } //填充数据,这里直接赋值为0,会画一个黑色窗口 *data = 0;         err = buff->unlock(); if (err != NO_ERROR) { ALOGE("unlock buffer err...."); } //将填充好的buffer送到SurfaceFlinger进行合成显示         err = surface->queueBuffer(surface, buff->getNativeBuffer(), -1); if (err != NO_ERROR) { ALOGE("queueBuffer buffer err...."); return err; }     mNativeBuffer = NULL;     IPCThreadState::self()->joinThreadPool(); return EXIT_SUCCESS; } //1.创建SurfaceComposerClient,这是SurfaceFlinger的Client端 void connectSurfaceFlinger(){          mSurfaceComposerClient = new SurfaceComposerClient;     err = mSurfaceComposerClient->initCheck(); if (err != NO_ERROR) { ALOGE("SurfaceComposerClient initCheck err...."); return; } } //2.创建Surface,ANativeWindow是创建Surface父类 sp<ANativeWindow> getSurface(){     sp<IBinder> display = SurfaceComposerClient::getInternalDisplayToken();     android::DisplayInfo mainDisplayInfo; //获取手机的屏幕信息     err = SurfaceComposerClient::getDisplayInfo(display, &mainDisplayInfo); if (err != NO_ERROR) { ALOGE("getDisplayInfo err...."); } //屏幕宽     mWidth = mainDisplayInfo.w; //屏幕高     mHeight = mainDisplayInfo.h; //创建surface对应surfaceflinger进程layer     mSurfaceControl = mSurfaceComposerClient->createSurface( String8("drawWindow"), mWidth/2, mHeight/2,             PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque); if (mSurfaceControl == NULL || !mSurfaceControl->isValid()) { ALOGE("mSurfaceControl err...."); } //获取surface     sp<ANativeWindow> anw = mSurfaceControl->getSurface(); return anw; } //3.Surface连接BufferQueue void connectBufferQueue(ANativeWindow *surface){     err = native_window_api_connect(surface, NATIVE_WINDOW_API_CPU); if (err != NO_ERROR) { ALOGE("connect bufferqueue err...."); } } //4.设置buffer数据 void setBufferTransaction(){ /*     setLayer():设置窗口的Z-order     setPosition():设置窗口显示的位置     show():设置窗口显示出来     apply():将设置的窗口信息应用到SurfaceFlinger,真正生效     */     SurfaceComposerClient::Transaction{} .setLayer(mSurfaceControl, 0x7FFFFFFF) .setPosition(mSurfaceControl,mWidth/4,mHeight/4) .show(mSurfaceControl) .apply(); } //5.设置buffer void setBuffer(ANativeWindow *surface){ //设置usage     err = native_window_set_usage(surface, GRALLOC_USAGE_SW_WRITE_OFTEN); if (err != NO_ERROR) { ALOGE("native_window_set_usage err...."); } //设置transform     err = native_window_set_buffers_transform(surface, NATIVE_WINDOW_TRANSFORM_ROT_90); if (err != NO_ERROR) { ALOGE("native_window_set_buffers_transform err...."); } //设置scaling_mode     err = native_window_set_scaling_mode(             surface, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); if (err != NO_ERROR) { ALOGE("native_window_set_scaling_mode err...."); } } setBuffer函数,里面调用了一系列native_window_set_XXX函数来个Surface设置各种信息,其实最终都是调用到Surface中setXXX函数,native_window_set_XXX是给外部调用提供操作Surface的接口,这些函数定义在frameworks/native/libs/nativewindow/include/system/window.h中,举个例子看看native_window_set_usage函数static inline int native_window_set_usage(struct ANativeWindow* window, uint64_t usage) { return window->perform(window, NATIVE_WINDOW_SET_USAGE64, usage); } ANativeWindow的perform函数:int (*perform)(struct ANativeWindow* window, int operation, ... ); Surface构造函数中赋值的: ANativeWindow::perform          = hook_perform; int Surface::hook_perform(ANativeWindow* window, int operation, ...) {     va_list args; va_start(args, operation);     Surface* c = getSelf(window); int result = c->perform(operation, args); va_end(args); return result; } hook_perform函数又调用Surface的perform函数:int Surface::perform(int operation, va_list args) { int res = NO_ERROR; switch (operation) { case NATIVE_WINDOW_CONNECT: // deprecated. must return NO_ERROR. break; case NATIVE_WINDOW_DISCONNECT: // deprecated. must return NO_ERROR. break; case NATIVE_WINDOW_SET_USAGE:         res = dispatchSetUsage(args); break; case NATIVE_WINDOW_SET_CROP:         res = dispatchSetCrop(args); break; case NATIVE_WINDOW_SET_BUFFER_COUNT:         res = dispatchSetBufferCount(args); ....... } dispatchXXX,比如native_window_set_usage传递的就是NATIVE_WINDOW_SET_USAGE64,从而调用dispatchSetUsage64:case NATIVE_WINDOW_SET_USAGE64:         res = dispatchSetUsage64(args); break; dispatchSetUsage64又调用setUsage最终将数据设置给了Surfaceint Surface::dispatchSetUsage64(va_list args) { uint64_t usage = va_arg(args, uint64_t); return setUsage(usage); } dequeueBuffer和queueBuffer中都有相关判断,比如宽高不能小于0,必须连接BufferQueue等。
 
 push进手机:
 adb push out/target/product/SEOUL_ATT/system/bin/drawWindow  /system/bin
 效果如下:
 
 通过这一个测试程序结合前几篇理论的文章可以更好的熟悉Android图形架构。
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算
 官方软件产品操作指南 (170)
官方软件产品操作指南 (170)