当前位置: 首页 > news >正文

Flutter3引用原生播放器-Android篇

接上篇:Flutter3引用原生播放器-IOS(Swift)篇

安卓端原生播放器的接入思路与ios基本一致,所以本篇就不废话了,直接上代码:

创建插件VideoViewPlugin实现FlutterPlugin:

package io.flutter.plugins.videoplayer;import android.util.Log;import androidx.annotation.NonNull;import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;public class VideoViewPlugin implements FlutterPlugin, ActivityAware {private final static String TAG = "VideoViewPlugin";FlutterPluginBinding fpBinding;@Overridepublic void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {fpBinding = binding;Log.e(TAG, "onAttachedToEngine");}@Overridepublic void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {Log.e(TAG, "onDetachedFromEngine");}@Overridepublic void onAttachedToActivity(@NonNull ActivityPluginBinding apBinding) {fpBinding.getPlatformViewRegistry().registerViewFactory("plugins.my_video_player/view", new VideoViewFactory(fpBinding, apBinding));Log.e(TAG, "onAttachedToActivity");}@Overridepublic void onDetachedFromActivityForConfigChanges() {Log.e(TAG, "onDetachedFromActivityForConfigChanges");}@Overridepublic void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {Log.e(TAG, "onReattachedToActivityForConfigChanges");}@Overridepublic void onDetachedFromActivity() {Log.e(TAG, "onDetachedFromActivity");}
}

由于引用视频播放器时需要用到Activity的context,所以实现了ActivityAware接口,在onAttachedToActivity方法中注册PlatformViewFactory!

创建VideoViewFactory实现PlatformViewFactory:

package io.flutter.plugins.videoplayer;import android.content.Context;import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;public class VideoViewFactory extends PlatformViewFactory {private final static String TAG = "VideoViewFactory";private final FlutterPlugin.FlutterPluginBinding fpBinding;private final ActivityPluginBinding apBinding;public VideoViewFactory(FlutterPlugin.FlutterPluginBinding fpBinding, ActivityPluginBinding apBinding) {super(StandardMessageCodec.INSTANCE);Log.e(TAG, "VideoViewFactory");this.fpBinding = fpBinding;this.apBinding = apBinding;}@Overridepublic PlatformView create(Context context, int viewId, Object args) {Log.e(TAG, "PlatformView-create:" + args.toString());return new VideoViewPlayer(args.toString(), fpBinding, apBinding);}}

创建VideoViewPlayer,实现PlatformView和MethodChannel.MethodCallHandler:

package io.flutter.plugins.videoplayer;import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;import com.th.kjjl_flutter.R;
import com.videoplayer.player.VideoView;import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.platform.PlatformView;public class VideoViewPlayer implements PlatformView, MethodChannel.MethodCallHandler {private final static String TAG = "VideoPlayerView";Activity context;private VideoView videoView;private MethodChannel methodChannel;VideoViewPlayer(String viewId, FlutterPlugin.FlutterPluginBinding fpBinding, ActivityPluginBinding apBinding) {this.context = apBinding.getActivity();videoView = (VideoView) LayoutInflater.from(context).inflate(R.layout.video_player, null);methodChannel = new MethodChannel(fpBinding.getBinaryMessenger(), "my_video_player_" + viewId);methodChannel.setMethodCallHandler(this);}@Overridepublic void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {Log.e(TAG, "call.method>>" + call.method);switch (call.method) {case "setUrl":String url = call.arguments.toString();videoView.initVideoController(context);videoView.setUrl(url);break;case "start":videoView.start();break;case "pause":videoView.pause();break;case "release":videoView.pause();videoView.release();break;case "stopFullScreen":videoView.stopFullScreen();break;default:result.notImplemented();}}@Nullable@Overridepublic View getView() {return videoView;}@Overridepublic void dispose() {Log.e(TAG, "dispose>>");videoView.pause();videoView.release();methodChannel.setMethodCallHandler(null);methodChannel = null;}}

其中的VideoView即引用的第三方播放器库,你可以根据自己情况,使用常见的安卓端开源播放器如GSY,饺子,DKPlayer等!

video_player.xml:

<?xml version="1.0" encoding="utf-8"?>
<com.videoplayer.player.VideoView xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/videoView"android:layout_width="match_parent"android:layout_height="match_parent" />

在MainActivity中注册插件:

class MainActivity : FlutterActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)flutterEngine!!.plugins.add(VideoViewPlugin())}
}

注意:不要在GeneratedPluginRegistrant中去注册插件包括IOS,这个类由系统自动生成其它第三方插件注册代码!安卓端在MainActivity中注册,IOS端在AppDelegate中注册!

flutter中的引用以及通信方法,上一篇已经写了,本篇就不再重复了!需要注意的是,插件名,插件id,methodChannel等,安卓,IOS和Flutter三端一定要一致!

相关文章:

Flutter3引用原生播放器-Android篇

接上篇&#xff1a;Flutter3引用原生播放器-IOS(Swift)篇 安卓端原生播放器的接入思路与ios基本一致&#xff0c;所以本篇就不废话了&#xff0c;直接上代码&#xff1a; 创建插件VideoViewPlugin实现FlutterPlugin&#xff1a; package io.flutter.plugins.videoplayer;imp…...

SerenityOS 操作系统类 Unix 操作系统

创建于2018年的SerenityOS是一个类似Unix的操作系统&#xff0c;但是带有图形化界面&#xff0c;适合X86台式计算机&#xff0c;&#xff0c;其界面类似90 年代的Win98/NT。几乎由一个人完成额操作系统。这几天其Web浏览器通过了 Acid3 浏览器。 Kernel features 具有抢占式多…...

Bean作用域和生命周期

目录 Bean作用域的例子 作用域定义 Bean的六种作用域 设置作用域 Spring的执行过程和Bean的生命周期 Spring的主要执行流程 Bean的生命周期 在上篇博客中我们使用Spring存储和获取Bean,因此Bean是Spring中最重要的资源,今天这篇博客就深入了解Bean对象 Bean作用域的例子 …...

STM32笔记

目录 1.1. 预备阶段 1.2. 单片机介绍 2. 初识STM32 2.1. STM32 1.1. 预备阶段 1.2. 单片机介绍 1.2.1. 单片机是什么 单片微型计算机(Single Chip Microcomputer)简称为单片机&#xff08;Microcontrollers&#xff09;&#xff0c;也称为微控制单元(Microcontroller Uni…...

【论文阅读】基于LevelDB的分布式数据库研究

基于LevelDB的分布式数据库研究 基于LevelDB的分布式数据库的研究与实现 - 中国知网 (cnki.net) 实现了什么&#xff1f; 基于键值型NoSQL数据库LevelDB&#xff0c;并与数据一致性算法Raft、 数据分片和负载均衡相结合&#xff0c;设计并实现基于LevelDB的分布式数据库。 主要…...

JavaScript高级 Iterator Generator

1. Iterator 1. JavaScript迭代器协议 在JavaScript中&#xff0c;迭代器也是一个具体的对象&#xff0c;这个对象需要符合迭代器协议&#xff08;iterator protocol&#xff09;&#xff1a; ◼ 迭代器协议定义了产生一系列值&#xff08;无论是有限还是无限个&#xff09;…...

数字IC手撕代码--乐鑫科技(次小值与次小值出现的次数)

前言&#xff1a;本专栏旨在记录高频笔面试手撕代码题&#xff0c;以备数字前端秋招&#xff0c;本专栏所有文章提供原理分析、代码及波形&#xff0c;所有代码均经过本人验证。目录如下&#xff1a;1.数字IC手撕代码-分频器&#xff08;任意偶数分频&#xff09;2.数字IC手撕代…...

JavaScript DOM和BOM

目录 查找html元素 1.通过id 2.通过标签名 3.通过类名 DOM 1.创建动态的HTML内容 2.修改元素内容 3.改变HTML属性 4.改变css样式 DOM事件 DOM节点 1.添加HTML元素 2.删除HTML元素 浏览器对象 1.Window对象 2.Screen对象 3.History对象 4.Location对象 5.Navi…...

JUC并发编程(二)

一、过时方法 一些不推荐使用的方法已经过时&#xff0c;容易破坏同步代码块&#xff0c;使对象的锁得不到释放&#xff0c;进而造成线程死锁 二、守护线程 默认情况下&#xff0c;Java 进程需要等待所有线程都运行结束&#xff0c;才会结束。有一种特殊的线程叫做守护线程…...

Python控制CANoe使能TestCase

前面介绍了多种CANoe配置下的dbc文件添加,常见的配置我们能够常用的就是testcase的使能和环境变量的设置,针对于环境变量的问题,我们下次再进行详聊,今天主要聊一下测试脚本的使能。在做这块之前,我们第一步就需要了解我们的测试脚本的层级是都包含有哪些? 一、测试脚本结…...

sql的执行顺序

一.前言 在我们世家开发中,我们少不了和数据库打交道, 我们的持久层是与数据库打交道的, 少不了要用sql语句来请求数据库的数据, 前台(前端页面)请求到-->控制器(接口层)-->service(业务层)-->mapper或dao(持久层) 简图: 在持久层我们的sql是怎么执行的, 它的执行顺…...

java 8 中的实用技巧

1 判断2个对象是否相等Objects.equals(a, b)(1) 比较时&#xff0c; 若a 和 b 都是null, 则返回 true, 如果a 和 b 其中一个是null, 另一个不是null, 则返回false。注意&#xff1a;不会抛出空指针异常。(2) a 和 b 如果都是空值字符串&#xff1a;"", 则 a.equals(b…...

自学大数据的第一天

默认跳过基础部分,直接搞集群的部分,期间用到的linux基础默认大伙都会了(不会的话可以现用现查) Hadoop集群搭建 集群特点: 1,逻辑上分离~集群之间没有依赖,互不影响 2,某些进程往往部署在一台服务器上,但是属于不同的集群 3,MapReduce 是计算框架,代码层面的处理逻辑 集群的…...

redis秒杀

redis优惠券秒杀 为什么订单表订单ID不采用自增长&#xff1f; id规律性太明显&#xff0c;容易被用户猜测到&#xff08;比如第一天下订单id10&#xff0c;第二天下订单id100&#xff0c;在昨天的1天内只卖出90商品&#xff09;受单表数据量限制&#xff08;订单数据量大&am…...

JS学习第3天——Web APIs之DOM(什么是DOM,相关API【创建、增删改查、属性操作、事件操作API】)

目录一、Web APIs介绍1、API2、Web API二、DOM1、DOM树2、获取元素3、事件基础4、操作元素属性5、节点&#xff08;node&#xff09;操作三、DOM操作总结&#xff08;创建、增删改查、属性操作、事件操作API&#xff09;1、创建2、增3、删4、改5、查6、属性操作7、事件操作四、…...

【MySQL】增删改操作(基础篇)

目录 1、新增操作(Create) 1.1 单行数据 全列插入 1.2 多行数据 全列插入 1.3 单行数据 指定列插入 2、修改操作(Update) 3、删除操作(Delete) 1、新增操作(Create) 如何给一张表新增数据呢&#xff1f; 新增(Create)&#xff0c;在我们数据库中&#xff0c;用 ins…...

STM32—DMA

什么是DMA&#xff1f; DMA(Direct Memory Access&#xff0c;直接存储器访问) 提供在外设与内存、存储器和存储器、外设与外设之间的高速数据传输使用。它允许不同速度的硬件装置来沟通&#xff0c;而不需要依赖于CPU&#xff0c;在这个时间中&#xff0c;CPU对于内存的工作来…...

C语言刷题(3)——“C”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容还是做几道题噢&#xff0c;好好复习一下之前的知识点&#xff0c;现在&#xff0c;就让我们开始复习吧 牛客网在线编程_编程学习|练习题_数据结构|系统设计题库 倒置字符串_牛客题霸_牛客网 BC40 竞选社长 BC41 你是天才…...

搭建Vue工程

搭建Vue工程 localhost 127.0.0.1 域名 IP 192.168.0.28 联网IP 最后都会渲染到一个页面里面&#xff0c;有多少个页面就有多少个页面模板。 vue里面改webpack配置 vue.config.js 配置参考 | Vue CLI /assets /api* 开发的时候用到的请求后台地址 和 项目真实部署上线的时候 请…...

C语言汉诺塔问题【图文详解】

汉诺塔1. 什么是汉诺塔2. 有关汉诺塔的有趣故事3. 利用动画来演示汉诺塔4. 如何用C语言实现汉诺塔1. 什么是汉诺塔 源于印度古老传说的益智玩具 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。大梵天创造…...

1、RocketMQ概述

文章目录1 MQ概述1.1 MQ简介1.2 MQ用途1.3 常见MQ产品1.4 MQ常见协议2 RocketMQ概述2.1 RocketMQ简介2.2 RocketMQ发展历程尚硅谷RocketMQ教程-讲师&#xff1a;Reythor雷&#xff08;老雷&#xff09; 我们缺乏的不是知识&#xff0c;而是学而不厌的态度 1 MQ概述 1.1 MQ简介…...

【POJ 3352】Road Construction 题解(Tarjan算法求边双连通分量缩点)

描述 现在几乎是夏天&#xff0c;这意味着几乎是夏天的施工时间&#xff01;今年&#xff0c;负责偏远岛热带岛屿天堂道路的好心人希望修复和升级岛上各个旅游景点之间的各种道路。 道路本身也很有趣。由于岛上的奇怪风俗&#xff0c;道路的安排使得它们不会在交叉路口相遇&…...

Python—单分支结构

&#xff08;1&#xff09;if分支语句 Python中if语句的语法结构&#xff1a; if <条件表达式>&#xff1a;    满足条件运行的代码1    满足条件运行的代码2 代码示例&#xff1a; age 12 if age > 18:print(去上网)if 1 1 2 and :print(我满足条件了)if 1 …...

rabbitmq添加用户,虚拟机步,设置rabbitmq配置文件

第一步&#xff0c;登录后台控制页面 http://ip:15672第二步&#xff0c;添加用户和权限 重点&#xff1a;选择Admin和Users 第三步&#xff0c;添加虚拟机 点击侧边的Virtual Hosts 第四步将虚拟机和用户搭配 注意新建好后&#xff0c;在虚拟机列表中&#xff0c;点击虚拟机…...

Codeforces Round#853 div2 A-C

Codeforces Round#853 div2 A-C 等了很久终于迎来了一场cf比赛&#xff0c;白天出去玩了一圈&#xff0c;晚上回来打比赛&#xff0c;这次只出了A,B题。C题思路很巧妙&#xff0c;赛时没做出来&#xff0c;看了大佬学习到了&#xff0c;还是很不错。 A.Serval and Mocha’s A…...

软考之操作系统知识

目录 1.进程管理-进程的概念 2.进程的三态图和五态图 3.进程的同步与互斥 4.PV操作应用 5.死锁问题 6.银行家算法 7.存储管理 8.段式存储组织 9.段页式存储组织 10.页面置换算法 11.磁盘管理 12.作业管理 13.索引文件结构 14.树型目录结构 15.空闲存储空间管理 …...

【线性代数/计算复杂性理论】积和式的指数时间算法:Ryser算法

文章目录一、积和式的定义二、Ryser算法三、代码实现一、积和式的定义 积和式&#xff08;permanent&#xff09;是一种和行列式长得很像的矩阵函数。在介绍积和式之前&#xff0c;我们先看看行列式&#xff08;determinant&#xff09;的定义。 首先需要引入“排列”&#x…...

代码随想录 NO52 | 动态规划_leetcode 647. 回文子串 516.最长回文子序列

动态规划_leetcode 647. 回文子串 516.最长回文子序列今天是动态规划最后一天的题了&#xff0c;整个过程已经接近尾声了&#xff01; 647. 回文子串 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 本题如果我们定义&#xff0c;dp[i] 为 下标i结尾的字符串有 dp…...

【数据挖掘】1、综述:背景、数据的特征、数据挖掘的六大应用方向、有趣的案例

目录一、背景1.1 学习资料1.2 数据的特征1.3 数据挖掘的应用案例1.4 获取数据集1.5 数据挖掘的定义二、分类三、聚类四、关联分析五、回归六、可视化七、数据预处理八、有趣的案例8.1 隐私保护8.2 云计算的弹性资源8.3 并行计算九、总结一、背景 1.1 学习资料 推荐书籍如下&a…...

【架构师】零基础到精通——康威定律

博客昵称&#xff1a;架构师Cool 最喜欢的座右铭&#xff1a;一以贯之的努力&#xff0c;不得懈怠的人生。 作者简介&#xff1a;一名Coder&#xff0c;软件设计师/鸿蒙高级工程师认证&#xff0c;在备战高级架构师/系统分析师&#xff0c;欢迎关注小弟&#xff01; 博主小留言…...