每一种操作系统都定义了自己的窗口系统,而 ANativeWindow 就是 Android 的本地窗口,在 Android Java 层,Surface 又继承于 ANativeWindow ,实际上 Surface 是 ANativeWindow 的具体实现,所以一个 ANativeWindow 表示的就是一块屏幕缓冲区。
我们要渲染一帧图像,只需要将图像数据刷进 ANativeWindow 所表示的屏幕缓冲区即可。
ANativeWindow的使用步骤大致如下:
- 通过
ANativeWindow_fromSurface
获取与Surface对应的ANativeWindow
对象 -
ANativeWindow_setBuffersGeometry
设置buffer的尺寸和格式 -
ANativeWindow_acquire
获取引用对象 - 利用
ANativeWindow_lock/ANativeWindow_unlockAndPost
与之间的绘制代码绘制图像 -
ANativeWindow_release
释放引用.
那ANativeWindow
和java的Surface
是什么关系呢?为什么可以通过ANativeWindow_fromSurface(env, surface);
得到ANativeWindow
源码中查找发现native_window.cpp
中调用了`android_view_Surface_getNativeWindow(env, surface);
// /frameworks/base/core/jni/android_view_Surface.cpp
sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj) {
sp<Surface> sur;
jobject lock = env->GetObjectField(surfaceObj,
gSurfaceClassInfo.mLock);
if (env->MonitorEnter(lock) == JNI_OK) {
sur = reinterpret_cast<Surface *>(
env->GetLongField(surfaceObj, gSurfaceClassInfo.mNativeObject));
env->MonitorExit(lock);
}
env->DeleteLocalRef(lock);
return sur;
}
可知就是通过获取android.view.Surface
这个class中的mNativeObject
属性获得到。查看Surface.java中mNativeObject
的赋值操作只有在:
private void setNativeObjectLocked(long ptr) {
...
mNativeObject = ptr;
...
}
而调用这个方法的都在构造方法或者状态恢复方法中。所以我们明白mNativeObject存储的其实就是一块内存地址,而通过这个内存地址可以直接强转获取到ANativeWindow
的地址指针。
关于java使用long存储地址可以查看JNI中用long传递指针到java