| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> 【Flutter原理】FlutterView相关源码分析,全套教学资料 -> 正文阅读 |
|
[移动开发]【Flutter原理】FlutterView相关源码分析,全套教学资料 |
================================================================= ? 通过前面文章的分析我们了解到FlutterActivity的显示最终是通过FlutterView进行渲染。本文我们深入FlutterView的源码来具体分析下Flutter UI是如何一步步显示到Activity,又是如何跟Flutter Engine关联,下面来看一下FlutterView的大致相关类: ========================================================================== 要了解FlutterView我们首先来了解一下Flutter的
public RenderMode getRenderMode() { return getBackgroundMode() == BackgroundMode.opaque ? RenderMode.surface : RenderMode.texture; } 说白了在FlutterActivity中RenderMode就是根据是否透明来决定,如果是透明窗体那么就使用
public RenderMode getRenderMode() { String renderModeName = getArguments().getString(ARG_FLUTTERVIEW_RENDER_MODE, RenderMode.surface.name()); return RenderMode.valueOf(renderModeName); } 而在FlutterFragment中RenderMode是通过
显而易见三种渲染模式对应的在FlutterView创建时以来不同的类,分别是:FlutterSurfaceView,FlutterTextureView,FlutterImageView。下面我们一起来看看这三个类。 =================================================================================== 从文中开头大致的类图关系我们知道FlutterSurfaceView、FlutterTextureView和FlutterImageView都是FlutterView的一个成员变量,通过构造函数根据不同的渲染模式传递对应的参数对FlutterView进行初始化。 //继承自SurfaceView,实现RenderSurface接口 public class FlutterSurfaceView extends SurfaceView implements RenderSurface { private final SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { //… connectSurfaceToRenderer(); } @Override public void surfaceChanged( @NonNull SurfaceHolder holder, int format, int width, int height) { //… changeSurfaceSize(width, height); } @Override public void surfaceDestroyed(@NonNull SurfaceHolder holder) { //… disconnectSurfaceFromRenderer(); } }; private void connectSurfaceToRenderer() { if (flutterRenderer == null || getHolder() == null) { throw new IllegalStateException( “connectSurfaceToRenderer() should only be called when flutterRenderer and getHolder() are non-null.”); } flutterRenderer.startRenderingToSurface(getHolder().getSurface()); } /**
*/ public void attachToRenderer(@NonNull FlutterRenderer flutterRenderer) { connectSurfaceToRenderer(); } /*** 当 FlutterSurfaceView 不再想将 Flutter UI 渲染到此 FlutterSurfaceView 时,由此 FlutterSurfaceView 的所有者调用。此方法将停止从 Flutter 到此 FlutterSurfaceView 的任何正在进行的渲染。 ***/ public void detachFromRenderer() { disconnectSurfaceFromRenderer(); } // FlutterRenderer and getSurfaceTexture() must both be non-null. private void connectSurfaceToRenderer() { flutterRenderer.startRenderingToSurface(getHolder().getSurface()); } // FlutterRenderer must be non-null. private void changeSurfaceSize(int width, int height) { flutterRenderer.surfaceChanged(width, height); } // FlutterRenderer must be non-null. private void disconnectSurfaceFromRenderer() { flutterRenderer.stopRenderingToSurface(); } } ? 上面的代码逻辑相当简介易懂,可以看到,FlutterSurfaceView实际上是一个SurfaceView,用法也是跟SurfaceView一样,只是渲染数据是最终是通过flutterJNI作为桥梁实现Flutter Engine与Android View层进行数据传递实现界面绘制的。 =================================================================================== 与上面的FlutterSurfaceView一样,逻辑实现简洁易懂,先看看主要逻辑: //继承自TextureView,实现RenderSurface接口 public class FlutterTextureView extends TextureView implements RenderSurface { private final SurfaceTextureListener surfaceTextureListener = new SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable( SurfaceTexture surfaceTexture, int width, int height) { connectSurfaceToRenderer(); } @Override public void onSurfaceTextureSizeChanged( @NonNull SurfaceTexture surface, int width, int height) { changeSurfaceSize(width, height); } @Override public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) { // Invoked every time a new frame is available. We don’t care. } @Override public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) { disconnectSurfaceFromRenderer(); return true; } }; public void attachToRenderer(@NonNull FlutterRenderer flutterRenderer) { connectSurfaceToRenderer(); } public void detachFromRenderer() { disconnectSurfaceFromRenderer(); } private void connectSurfaceToRenderer() { renderSurface = new Surface(getSurfaceTexture()); flutterRenderer.startRenderingToSurface(renderSurface); } private void changeSurfaceSize(int width, int height) { flutterRenderer.surfaceChanged(width, height); } private void disconnectSurfaceFromRenderer() { flutterRenderer.stopRenderingToSu
rface(); if (renderSurface != null) { renderSurface.release(); renderSurface = null; } } } 从上面的代码可以看到FlutterTextureView和FlutterSurfaceView的逻辑基本一致,唯一不同的就是提供的Surface来源不一样,逻辑很简单这里不做多余介绍。 ================================================================================= FlutterImageView并不是一个真正意义上的ImageView。它的工作流程和FlutterTextureView,FlutterSurfaceView工作流程极度相似,但是它的使用场景却完全不一样,想要了解FlutterImageView的工作场景,必须要先了解Flutter的Hybrid Composition工作模式。由于Hybrid Composition 模式涉及到的内容关联比较多,下次单独讲解。这里简单理解来讲Hybrid Composition模式就是解决原生控件和Flutter混合显示问题。 我们来看下FlutterImageView源码: @TargetApi(19) public class FlutterImageView extends View implements RenderSurface { // 原生控件的绘制操作 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (!imageQueue.isEmpty()) { if (currentImage != null) { currentImage.close(); } currentImage = imageQueue.poll(); updateCurrentBitmap(); } if (currentBitmap != null) { canvas.drawBitmap(currentBitmap, 0, 0, null); } } } 我们可以看到FlutterImageView实际上就是一个原生的View,但是它又实现了RenderSurface接口,不难判断FlutterImageView既可以显示渲染我们的FlutterUI,又可以显示渲染我们的原生View。它的使用场景已经原理分享后面再花费专题文章讲解。 ============================================================================== 通过上面的分析,我们知道FlutterRenderer 的主要职责最终是通过 FlutterJNI 进行渲染关联处理,与原生平台提供的 FlutterSurfaceView、FlutterTextureView 、FlutterImageView进行纯 UI 渲染,将 Flutter 像素绘制到 Android 视图层次结构。 public class FlutterRenderer implements TextureRegistry { //… @NonNull private final FlutterJNI flutterJNI; @Nullable private Surface surface; //… } 通过上面源码的两个属性成员就能看出来他的职责。 ============================================================================ 通俗来说FlutterView 的作用是在 Android 设备上显示一个 Flutter UI,绘制内容来自于 FlutterEngine 的flutterJNI提供。FlutterView常用模式下有两种渲染模式:
这种模式性能最好,但是这种模式下的一个 FlutterView 不能定位在 z-index 中其他 2 个 Android Views 之间,也不能进行动画/转换。除非需要 android.graphics.SurfaceTexture 的特殊功能,否则强烈建议开发人员使用这种渲染模式。 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 5:34:28- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |