type
status
date
slug
summary
tags
category
icon
password
ANativeWindow是什么
ANativeWindow是C/C++中定义的一个结构体,等同于Java中的
Surface
.Android NDK中可以访问到ANativeWindow.
ANativeWindow中存放像素信息的结构是:
ANativeWindow_Buffer
:typedef struct ANativeWindow_Buffer { /// The number of pixels that are shown horizontally. int32_t width; /// The number of pixels that are shown vertically. int32_t height; /// The number of *pixels* that a line in the buffer takes in /// memory. This may be >= width. int32_t stride; /// The format of the buffer. One of AHardwareBuffer_Format. int32_t format; /// The actual bits. void* bits; /// Do not touch. uint32_t reserved[6]; } ANativeWindow_Buffer;
主要API
- 获取与surface对应的ANativeWindow
ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);
- 保持/释放ANativeWindow对象的引用
void ANativeWindow_acquire(ANativeWindow* window); void ANativeWindow_release(ANativeWindow* window);
- 向buffer中写入数据并提交
int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); // 这之间的代码可以执行一些向buffer中写入数据的操作 int32_t ANativeWindow_unlockAndPost(ANativeWindow* window);
- 获取Window Surface的信息:宽/高/像素格式
int32_t ANativeWindow_getWidth(ANativeWindow* window); int32_t ANativeWindow_getHeight(ANativeWindow* window); int32_t ANativeWindow_getFormat(ANativeWindow* window);
像素格式定义在
AHARDWAREBUFFER_FORMAT_*
- 改变Window Buffer的格式和大小
int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width, int32_t height, int32_t format);
一般的流程
- 通过
ANativeWindow_fromSurface
获取与Surface对应的ANativeWindow
对象
ANativeWindow_setBuffersGeometry
设置buffer的尺寸和格式
ANativeWindow_acquire
获取引用对象
- 利用
ANativeWindow_lock/ANativeWindow_unlockAndPost
与之间的绘制代码绘制图像
ANativeWindow_release
释放引用.
一个简单的例子
写个简单的例子:利用ANativeWindow绘制一个灰色的背景.
- C++代码
#include <jni.h> #include <string> #include <android/native_window.h> #include <android/native_window_jni.h> void drawColor(JNIEnv *env,jobject obj,jobject surface, jint colorARGB) { int alpha = colorARGB >> 24 & 0xFF; int red = colorARGB >> 16 & 0xFF; int green = colorARGB >> 8 & 0xFF; int blue = colorARGB & 0xFF; int colorABGR = alpha << 24 | (blue << 16) | (green << 8) | red; ANativeWindow *window = ANativeWindow_fromSurface(env,surface); int32_t result = ANativeWindow_setBuffersGeometry(window,640,640,AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM); if (result < 0){ ANativeWindow_release(window); window = nullptr; return; } ANativeWindow_acquire(window); ANativeWindow_Buffer buffer; if (ANativeWindow_lock(window,&buffer, nullptr) < 0){ ANativeWindow_release(window); window = nullptr; return; } auto *line = (uint32_t *) buffer.bits; for (int y = 0; y < buffer.height; ++y) { for (int x = 0; x < buffer.width; ++x) { line[x] = colorABGR; } line += buffer.stride; } if (ANativeWindow_unlockAndPost(window) < 0){ return; } ANativeWindow_release(window); } extern "C" JNIEXPORT void JNICALL Java_com_jiangkang_androiddemos_MainActivity_drawColor(JNIEnv *env, jobject thiz, jobject surface, jint color) { drawColor(env,thiz,surface,color); }
- Activity代码
import android.graphics.Color import android.os.Bundle import android.view.Surface import android.view.SurfaceHolder import androidx.appcompat.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) surface_view.holder.addCallback(object : SurfaceHolder.Callback2 { override fun surfaceRedrawNeeded(holder: SurfaceHolder?) { } override fun surfaceChanged( holder: SurfaceHolder?, format: Int, width: Int, height: Int ) { } override fun surfaceDestroyed(holder: SurfaceHolder?) { } override fun surfaceCreated(holder: SurfaceHolder?) { holder?.let { drawColor(it.surface, Color.GRAY) } } }) } external fun drawColor(surface: Surface, color: Int) companion object { init { System.loadLibrary("native-lib") } } }
总结
- Native层中的
ANativeWindow
对应Java层中的Surface
,因此可以利用SurfaceView + ANativeWindow,用C++代码绘制屏幕;
- 在图像/视频处理中会利用到
ANativeWindow
,也可以与EGL,FFMPEG等结合使用
- Flutter Engine中正是通过
ANativeWindow
才将Dart中的UI与Android中UI联系到一起的.
- 作者:姜康
- 链接:https://jiangkang.tech/article/4419e46b-0a34-41b7-b260-4484dd4c7b80
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章