App的启动过程(5)ViewTree遍历中最后一步的Draw
来源:互联网 发布:网络招生技巧 编辑:程序博客网 时间:2024/06/04 00:32
以上是WMS端窗口的添加,下面接着ViewTree遍历中最后一步的Draw的分析。
/* ViewRootImpl.java */
private boolean drawSoftware()à canvas =mSurface.lockCanvas(dirty);
跟View交互的是Canvas,比如draw(Canvas cs)参数,应用进程与surfaceflinger交互的是surface,即应用进程端的本地窗口,那么canvas和surface之间怎么协作的?
lockCanvas @Surface.java –>nativeLockCanvas@ android_view_Surface.cpp
static jlong nativeLockCanvas((){
//这个是C++层的surface对象
sp<Surface>surface(reinterpret_cast<Surface *>(nativeObject));
//获取一个存储UI数据的buffer,
ANativeWindow_BufferoutBuffer;
//通过IGraphicBufferProducer的dequeuBuffer,获取一个可用的buffer,
status_t err =surface->lock(&outBuffer, dirtyRectPtr);
//为bitmap分配内存空间,为bitmap分配可用的存储空间
SkBitmapbitmap;
bitmap.setInfo(info,bpr);
bitmap.setPixels(outBuffer.bits);
//构造本地层的canvas,第二个参数是canvasObj是java层的canvas对象
Canvas*nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
//给canvas这个作画的工具集设置作画的画纸,也就是bitmap,实际上bitmap的画纸来自于outBuffer,而outBuffer所指向的内存是surface通过lock去申请
nativeCanvas->setBitmap(bitmap);
//返回一个java层的surface
sp<Surface>lockedSurface(surface);
return (jlong)lockedSurface.get();
}
typedef struct ANativeWindow_Buffer {
// The number of pixels that are show 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. Oneof WINDOW_FORMAT_*
int32_t format;
// The actual bits.
void* bits;
// Do not touch.
uint32_t reserved[6];
} ANativeWindow_Buffer;
ANativeWindow_Buffer中的属性void*bits就是canvas中作画,存储数据的地方。
Surface的职责只是管理SurfaceFlinger分配的用于存储UI数据的内存块,它是一个中介,通过与SurfaceFlinger的协作满足上层的需求。
/* Surface.cpp */
status_t Surface::lock(){
// 当前是否有buffer被locked,因为被Locked的buffer只能有一个,以mLockedBuffer表示
if(mLockedBuffer != 0)
// 执行连接到CPU
interr = Surface::connect(NATIVE_WINDOW_API_CPU);
//设置内存块的用法,
setUsage(GRALLOC_USAGE_SW_READ_OFTEN| GRALLOC_USAGE_SW_WRITE_OFTEN);
//dequeue一个可用的buffer,是通过GraphicBufferProducer来向BufferQueue获取一个buffer,这里有frontBuffer,backBuffer分别代表上一次处理的buffer和当前正在处理的buffer,两次图像更新间通常不需要重绘整个区域,可以借助之前的buffer填充本次的buffer内容,判断是否可以从上一次的buffer中copy数据的依据就是buffer的宽、高、格式是否一致。不能copy就要重绘整个界面。
status_terr = dequeueBuffer(&out, &fenceFd);
//锁定buffer
status_tres = backBuffer->lockAsync()
}
status_t Surface::unlockAndPost(){
//UI绘制完成,需要解锁,Buffer入队,提交给SurfaceFlinger渲染,SurfaceFlinger后续会这一buffer进行处理,最终显示到屏幕上
status_terr = mLockedBuffer->unlockAsync(&fd);
err= queueBuffer(mLockedBuffer.get(), fd);
}
分析了native层canvas的实现机制,回到java层的performDraw
drawSoftware()@ViewRootImpl.javaà mView.draw(canvas);//同样从viewtree根元素开始
public void draw(){
//从View树的根元素开始,逐步往下绘制
mView.draw(canvas);
}
/*View.java*/
public void draw(Canvas canvas) {
//绘制背景,要考虑是否进行坐标变换
drawBackground(canvas);
//绘制内容,调用具体子类的onDraw方法
if(!dirtyOpaque) onDraw(canvas);
//递归绘制子对象,调用ViewGroup子类的实现
dispatchDraw(canvas);
//画scrollbar
onDrawScrollIndicators(canvas);
onDrawScrollBars(canvas);
}
onDraw就是具体的绘制,以ImageView为例
onDraw@ImageView.java{
//把drawable中内容绘制到这个canvas上
mDrawable.draw(canvas);
}
上面应用进程写完内容后,会解锁这个buffer并queueBuffer,把数据提交:
unlockCanvasAndPost@Surface.java-->unlockAndPost@Surface.cpp
在把这个buffer入队,即queuebuffer时,queueBuffer@BufferQueueProducer.cpp这个方法中,会通过sp<IConsumerListener>frameAvailableListener这个监听,把当前有可消费的buffer的这个事件通过onFrameAvailable发出去,这样buffer的消费者就会取这个buffer。
- App的启动过程(5)ViewTree遍历中最后一步的Draw
- Android GUI系统-ViewTree的遍历(四)
- 解决mysql start service安装过程中最后一步失败的问题
- iOS中一个APP的启动过程
- Android中APP的自启动过程
- App的启动过程
- View的draw过程
- 安装mysql 最后一步失败的解决方法
- 重装MySQL最后一步失败的解决办法
- Android App的启动过程
- Android App的启动过程
- App的启动过程(8)surfaceflinger的启动
- 020.View的Draw过程
- Android GUI系统-ViewTree的创建(二)
- Android GUI系统-ViewTree的管理者(三)
- Android APP启动过程中应用代码的加载
- App的启动过程(4)在WMS中注册窗口
- Android探索之旅(第十六篇)Android APP启动过程分析(1)——Measure、Layout、Draw
- volatile 浅显描述
- Fiddler:读取Response的body写入本地文件
- GA遗传算法(Genetic Algorithm)
- TimingWheel[时间轮]介绍
- Android Web开发调试之Chrome远程调试
- App的启动过程(5)ViewTree遍历中最后一步的Draw
- 【Maven学习】maven-assembly-plugin的使用
- 欢迎使用CSDN-markdown编辑器
- MYSQL命令大全
- MySQL学习笔记(3)
- SQL SERVER【非域环境】镜像之搭建篇
- react-native导航库react-navigation(一)
- EM从最大似然到EM算法浅解
- 基本过滤选择器、可见性过滤选择器