【Flutter原理】FlutterView相关源码分析

/***

当 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层进行数据传递实现界面绘制的。

FlutterTextureView分析

===================================================================================

与上面的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.stopRenderingToSurface();

if (renderSurface != null) {

renderSurface.release();

renderSurface = null;

}

}

}

从上面的代码可以看到FlutterTextureView和FlutterSurfaceView的逻辑基本一致,唯一不同的就是提供的Surface来源不一样,逻辑很简单这里不做多余介绍。

FlutterImageView分析

=================================================================================

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。它的使用场景已经原理分享后面再花费专题文章讲解。

FlutterRender分析

==============================================================================

通过上面的分析,我们知道FlutterRenderer 的主要职责最终是通过 FlutterJNI 进行渲染关联处理,与原生平台提供的 FlutterSurfaceView、FlutterTextureView 、FlutterImageView进行纯 UI 渲染,将 Flutter 像素绘制到 Android 视图层次结构。

public class FlutterRenderer implements TextureRegistry {

//…

@NonNull private final FlutterJNI flutterJNI;

@Nullable private Surface surface;

//…

}

通过上面源码的两个属性成员就能看出来他的职责。

FlutterView分析

============================================================================

通俗来说FlutterView 的作用是在 Android 设备上显示一个 Flutter UI,绘制内容来自于 FlutterEngine 的flutterJNI提供。FlutterView常用模式下有两种渲染模式:

  1. RenderMode.surface

这种模式性能最好,但是这种模式下的一个 FlutterView 不能定位在 z-index 中其他 2 个 Android Views 之间,也不能进行动画/转换。除非需要 android.graphics.SurfaceTexture 的特殊功能,否则强烈建议开发人员使用这种渲染模式。

  1. RenderMode.texture

它将 Flutter UI 绘制到 android.graphics.SurfaceTexture。这种模式的性能不如 io.flutter.embedding.android.RenderMode.surface,但这种模式下的 FlutterView 可以进行动画和变换,也可以定位在 2+ 其他 Android 视图之间的 z-index 中。除非需要 android.graphics.SurfaceTexture 的特殊功能,否则开发人员应该强烈推荐

FlutterView 的默认构造器就是 surface 模式

下面我们再来分析下FlutterView,首先我们来看看它的变量和构造函数声明

public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseCursorViewDelegate {

private static final String TAG = “FlutterView”;

// 用来真正渲染绘制视图的相关类

@Nullable private FlutterSurfaceView flutterSurfaceView;

@Nullable private FlutterTextureView flutterTextureView;

@Nullable private FlutterImageView flutterImageView;

@Nullable private RenderSurface renderSurface;

@Nullable private RenderSurface previousRenderSurface;

//与 FlutterEngine连接

@Nullable private FlutterEngine flutterEngine;

// 处理各种类型的 Android View 输入和事件的组件

@Nullable private MouseCursorPlugin mouseCursorPlugin;

@Nullable private TextInputPlugin textInputPlugin;

@Nullable private LocalizationPlugin localizationPlugin;

@Nullable private AndroidKeyProcessor androidKeyProcessor;

@Nullable private AndroidTouchProcessor androidTouchProcessor;

@Nullable private AccessibilityBridge accessibilityBridge;

//构造函数,默认模式为surface

private FlutterView(

@NonNull Context context,

@Nullable AttributeSet attrs,

@NonNull FlutterSurfaceView flutterSurfaceView) {

super(context, attrs);

this.flutterSurfaceView = flutterSurfaceView;

this.renderSurface = flutterSurfaceView;

init();

}

//构造函数,模式为texture

private FlutterView(

@NonNull Context context,

@Nullable AttributeSet attrs,

@NonNull FlutterTextureView flutterTextureView) {

super(context, attrs);

this.flutterTextureView = flutterTextureView;

this.renderSurface = flutterTextureView;

init();

}

//构造函数 模式为image

@TargetApi(19)

private FlutterView(

@NonNull Context context,

@Nullable AttributeSet attrs,

@NonNull FlutterImageView flutterImageView) {

super(context, attrs);

this.flutterImageView = flutterImageView;

this.renderSurface = flutterImageView;

init();

}

//根据不同的模式指定RenderSurface

private void init() {

if (flutterSurfaceView != null) {

addView(flutterSurfaceView);

} else if (flutterTextureView != null) {

addView(flutterTextureView);

} else {

addView(flutterImageView);

}

}

通过上面的代码我们知道FlutterView其实是一个原生的继承自FrameLayout的ViewGroup。在init中根据不同的模式添加不同的View从而指定_surface_,也就是 FlutterSurfaceView、FlutterTextureView、FlutterImageView 之一。而最终FlutterEngine渲染数据到不同的surface。


总结(类图,架构图)

=========================================================================

类关系图


在这里插入图片描述

架构图
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

总之啊,家里没矿的同学们,如果你们想以后的日子过得好一些,多想想你们的业余时间怎么安排吧;

技术方面的提升肯定是重中之重,但是技术外的一些“软实力”也不能完全忽视,很多时候升职确实是因为你的技术足够强,但也与你的“软实力”密切相关

在这我也分享一份大佬自己收录整理的 Android学习PDF+架构视频+面试文档+源码笔记 ,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅并给下属员工学习的精品资料。在脑图中,每个知识点专题都配有相对应的实战项目,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

相信自己,没有做不到的,只有想不到的

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

同学们,如果你们想以后的日子过得好一些,多想想你们的业余时间怎么安排吧;

技术方面的提升肯定是重中之重,但是技术外的一些“软实力”也不能完全忽视,很多时候升职确实是因为你的技术足够强,但也与你的“软实力”密切相关

在这我也分享一份大佬自己收录整理的 Android学习PDF+架构视频+面试文档+源码笔记 ,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅并给下属员工学习的精品资料。在脑图中,每个知识点专题都配有相对应的实战项目,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

[外链图片转存中…(img-QY692jeF-1711910297448)]

[外链图片转存中…(img-C2yYA67S-1711910297448)]

相信自己,没有做不到的,只有想不到的

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值