车载音视频App框架设计
简介
统一播放器提供媒体播放一致性的交互和视觉体验,减少各个媒体应用和场景独自开发的重复工作量,实现媒体播放链路的一致性,减少碎片化的Bug。本文面向应用开发者介绍如何快速接入媒体播放器。
主要功能:
- 新设计的统一播放UI组件,视频支持的手势操作,包括左右滑拖动进度、左上下滑调节亮度、右上下滑调节音量、双击暂停/播放,同时对外暴露了长按手势接口应用可以实现类似快进快退功能;
- 支持方控、Mini播放器、PSD的播控和状态显示,应用只需要申请媒体中心权限的license即可,支持媒体中心的状态保持和语音控制通道,需要APP中接入对应的接口;
- 支持视频行车娱乐限制,非P档播放视频会暂停播放弹框提示;
- 使用原生的的media3 1.3.0版本,支持原生的androidx 和framework media session;
- 支持音频焦点自管理,包括电话状态的播控也基于音频焦点统一处理;
整体架构图如下
- 应用通过配置UI,然后创建MediaController播放媒体;
- controler端接入了行车娱乐限制的检测和提示;
- service端实现了google原生的media3 session service;
- 媒体中心通过mediasession和播放器连接;
- 底层使用media3 exoplayer播放和音频焦点管理;
接入流程
1、配置依赖
implementation 'com.max.mediaplayer:uniteplayer:1.x.x
备注:uniteplayer中包含了视频控制UI组件,当只需要修复控制UI组件的bug时,可以更新整体uniteplayer播放器组件,也可以只增加UI组件的依赖,比如:implementation (‘com.max.media:media-video:1.2.0’)。
2、初始化
建议在application创建的时候调用初始化接口:
init(context: Context, isVideo: Boolean, enableMediaCenter: Boolean = false)
参数 | 说明 |
---|---|
context | 应用context |
isVideo | 是否视频应用,视频会初始化车机相关的adapterapi,音乐目前不会初始化 |
enableMediaCenter | 需要远程方控、语音控制、mini播放器控制这些能力时设置为true,否则为false,默认为false |
3、接入 UI 组件 (视频应用)
这里的UI组件只针对视频应用,音频应用的UI组件在媒体组件库中,参考媒体视频组件。
1)配置PlayerView
在布局中增加FlexPlayerView,视频内容显示和播控UI都在此view中,一般默认配置如下即可:
<com.max.uniteplayer.ui.FlexPlayerViewandroid:id="@+id/player_view"android:layout_width="match_parent"android:layout_height="match_parent"/>
其中播控UI是可单独接入的,若需定制,接入见视频组件接入文档。
2)配置视频渲染view
一般情况下不需要特别配置,支持的定制视频显示view参数如下:
比如在上面FlexPlayerView xml中用app:surface_type=“surface_view”
surface_type:surface类型,取值如下,默认是surface_view类型:
<attr name="surface_type" format="enum"> <enum name="none" value="0"/> <enum name="surface_view" value="1"/> <enum name="texture_view" value="2"/> <enum name="spherical_gl_surface_view" value="3"/> <enum name="video_decoder_gl_surface_view" value="4"/></attr>
resize_mode,取值如下,默认fit模式:
<attr name="resize_mode" format="enum"> <enum name="fit" value="0"/> <enum name="fixed_width" value="1"/><enum name="fixed_height" value="2"/> <enum name="fill" value="3"/> <enum name="zoom" value="4"/> </attr>
first_render_delay,首帧显示延迟时长,用于规避首帧渲染慢闪拉伸的问题,int型,单位ms,一舨不需要设置,默认0;
3)配置视频播控View
FlexPlayerView本身对外暴露了两个接口:
接口 | 说明 |
---|---|
fun setTitleBarVisible(visible: Boolean) | 因此视频播放器中顶部title和关闭按钮,一般应用自己实现的可以通过此接口隐藏 |
fun enableUpDownGesture(enable: Boolean) | 使能上下滑动,默认播放器是支持的,可以设置false关闭 |
bindControlView(listener: FlexPlayerView.ControlViewListener) | 获取视频播控view控制器,提供更多配置能力,比如增加手势监听回调、添加自定义的播控按钮等,具体可以参考视频组件接入文档。 |
4、使用播放器播放
有3种播放接口,选择其中一个:
1)FlexSimplePlayer
封装的最高层播放接口,内部封装好了原生MediaItem对象,简单的视频播放场景推荐使用此接口:
class FlexSimplePlayer(context: Context?,isVideo: Boolean,enableParkDetect: Boolean = true,enableParkDialog: Boolean = true,controllerCallback: FlexControllerCallback? = null)
参数说明:
参数 | 说明 |
---|---|
context | 上下文; |
enableParkDetect | 只针对视频生效,是否启用行车娱乐限制,非驻车档会自动暂停视频播放(默认是强制要求的); |
enableParkDialog | 只针对视频生效,是否弹出行车娱乐限制框,设置为disable后需要应用可以自己实现提示界面; |
开始播放:
player.startPlay(context: Context,mediaData: List<MediaData>,view: FlexPlayerView?,listener: FlexMediaListener?,mediaCenterData: MediaCenterData? = null)
参数说明:
参数 | 说明 |
---|---|
context | 上下文,注意视频播放要使用activity的context,因为行车娱乐限制需要弹框 |
mediaData | 媒体列表,每个媒体item包括url、metadata、mimetiype,其中url是媒体地址,可以是本地、在线点播或直播地址,medadata是media3的原始类型,title和artist字段会显示在mini播放器和PSD上,mimeTypes指定媒体类型,url是对应后缀的无需设置,有些比如优酷投屏中有一个直播url是/m3u8结尾 而不是.m3u8结尾 需要设置mimeTypes = MimeTypes.APPLICATION_M3U8; |
view | 类型为FlexPlayerView,自实现UI的此参数设置为null |
listener | 媒体播放监听回调,具体回调接口后面详细展开,不需要监听设置为null |
mediaCenterData | 媒体中心中需要用的数据,比如应用包名、图标等,具体类型后面详细展开,这里需要注意的是sourceType要设置为6,在媒体中心中对应SourceType.SOURCE_TYPE_ONLINE。 |
controllerCallback | 媒体中心回调的方法,包括播放/暂停、上/下曲切换,在此回调中可以实现自定义处理逻辑,并屏蔽底层播放器的响应; |
退出界面停止播放,停止播放后会释放所有播放资源:
player.stopPlay()
页面切换的处理建议:
视频应用界面退到后台(onPuse)暂停: player.pause()
视频应用从后台回到前台(onResume): player.play()
更新播放列表:
fun updateMediaItems(mediaData: List<MediaData>)
在已经进入播放状态下,更换播放的视频建议使用该接口,避免重新startPlay()会更慢。
2)FlexMediaController
音频类应用复杂场景建议使用该接口。
FlexSimplePlayer下层的接口,使用该接口需要自己创建MediaItem,mimeType需要调用util接口设置。适合需要自己构建比较复杂的mediaitem场景,另外没有直接提供暂停和播放接口,需要调用成员player的暂停和播放接口。
构造方法解释同FlexSimplePlayer。
开始播放:
fun startPlay(context: Context,mediaItems: List<MediaItem>,view: FlexPlayerView?,listener: FlexMediaListener?,customData: MediaCenterData?,controllerCallback: FlexControllerCallback? = null)
参数说明:
参数 | 说明 |
---|---|
context | 上下文,注意视频播放要使用activity的context,因为行车娱乐限制需要弹框 |
mediaItems | 媒体列表,原生类型,包括媒体url,metadata,mimetype等 |
view | 类型为FlexPlayerView,自实现UI的此参数设置为null |
listener | 媒体播放监听回调,具体回调接口后面详细展开,不需要监听设置为null |
mediaCenterData | 媒体中心中需要用的数据,比如应用包名、图标等,具体类型后面详细展开,这里需要注意的是sourceType要设置为6,在媒体中心中对应SourceType.SOURCE_TYPE_ONLINE。 |
controllerCallback | 媒体中心回调的方法,包括播放/暂停、上/下曲切换,在此回调中可以实现自定义处理逻辑,并屏蔽底层播放器的响应; |
FlexControllerCallback接口:
interface FlexControllerCallback {companion object {const val KEY_ACTION_TYPE = "actionType"const val KEY_CALLBACK_RESULT = "callbackResult"const val TYPE_PLAY = 1const val TYPE_NEXT = 2const val TYPE_PREVIOUS = 3const val RESULT_OK = 0const val RESULT_BLOCK = 1}fun onDefaultCallback(bundle: Bundle): Bundle?{return Bundle.EMPTY}fun onPlayAction(): Int?{return RESULT_OK}fun onSeekToNext(): Int?{return RESULT_OK}fun onSeekToPrevious(): Int?{return RESULT_OK}
}
接口描述:
接口 | 说明 |
---|---|
onPlayAction(): Int? | 媒体中心调用过来的播放/暂停接口 |
onSeekToNext(): Int? | 媒体中心调用过来的下一首接口 |
onSeekToPrevious(): Int? | 媒体中心调用过来的上一首接口 |
退出界面停止播放,停止播放后会释放所有播放资源:
player.stopPlay()
页面切换的处理建议:
视频应用界面退到后台(onPuse)暂停: player.player?.pause()
视频应用从后台回到前台(onResume): player.player?.play()
更新播放列表:
fun updateMediaItems(mediaItems: List<MediaItem>)
在已经进入播放状态下,更换播放的视频建议使用该接口,避免重新startPlay()会更慢。
3)FlexExoPlayerController
此接口一般不会用到,前面两个接口默认会启动sessionservice,支持媒体中心的连接,此接口直接返回exoplayer播放器,不会创建mediasession,不支持媒体中心连接,支持视频行车娱乐限制。使用媒体UI组件和播放器需要在应用中自行对接,适用于定制化比较多,不需要远程播放支持的视频播放场景,目前只用在赛道模式。建议优先选用前面两种方式播放。
构造方法解释同FlexSimplePlayer。
fun getExoPlayer(audioFocus: Boolean = false,mediaListener: FlexMediaListener? = null): ExoPlayer?
参数和返回值:
参数 | 说明 |
---|---|
audioFocus | 是否打开音频焦点自管理,默认是false。在赛道模式情况存在两个视频同时播的情况,需要设置为false否则因为音频焦点抢占不能同时播放,其他场景建议设置为true; |
mediaListener | 状态回调,同前面两个接口,具体参数后面详细描述; |
返回值 | media3 ExoPlayer对象。 |
5、状态回调接口
自定义的播放回调接口:
interface FlexMediaListener{//player加载完成fun onLoadPlayerFinished(player: Player?) {}//返回true不会自动播放,需要调用play()后才能播放,默认falsefun pauseWhenStart(): Boolean {return false}//直接返回player的状态接口,更多复杂场景建议拿player对象处理fun onPlaybackStateChange(state: Int){}fun onPlayWhenReadyChanged(ready: Boolean, reason: Int) {}fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {}//播放异常fun onPlayerError(errorCode: Int, errorData: Bundle?) {}//只针对视频,播放视频时检测到非驻车状态回调,会自动暂停播放fun onStartVideoWhenNoPark() {}//只针对视频,非驻车播放视频,弹框点击关闭按钮后的回调fun onStopVideoWhenNoPark() {}//关闭播放页面fun onClose(){}//退出应用fun onExitApp() {}//Mote: This is callback from media center, not from playerfun onSeekToNext(): Boolean {return false}fun onSeekToPrevious(): Boolean {return false}
}
接口描述:
接口 | 说明 |
---|---|
onLoadPlayerFinished(player: Player?) | 开始播放是异步的调用,此回调表示已完成了到服务端的连接返回了有效的player接口 |
fun pauseWhenStart(): Boolean | 开始播放后是否自动暂停,需要用户手动点击播放,默认false |
fun onPlaybackStateChange(state: Int) fun onPlayWhenReadyChanged(ready: Boolean, reason: Int) fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) | 原生Player接口播放状态变化的透传,state取值:Player.STATE_IDLE:还未开始播放STATE_BUFFERING:缓冲中STATE_READY:准备好播放,结合PlayWhenReady状态来判断,true为播放中,false为暂停STATE_ENDED:播放结束onPlayWhenReadyChanged取值: true为播放中,false为暂停onMediaItemTransition:切歌可以通过这里判断 |
fun onPlayerError(errorCode: Int, errorData: Bundle?) | 播放异常,errorCode时原生的错误码,errorData暂时没有用到 |
fun onStartVideoWhenNoPark() | 只针对视频,档检测到非P档播放视频时会回调此接口 |
fun onStopVideoWhenNoPark() | 只针对视频,非P播放视频弹框后,点击关闭按钮或弹框自动退出时的回调 |
fun onClose() | 用户点击左上角关闭按钮 |
fun onExitApp() | 退出应用,暂未用到 |
fun onSeekToNext() | 方控或PSD切换下一曲操作会回调,返回true表示应用来接管下一曲操作不会调用底层播放器的下一曲接口,返回false底层会调用播放器的下一曲接口, 目前投屏用到 |
fun onSeekToPrevious() | 方控或PSD切换上一曲操作会回调,返回true表示应用来接管上一曲操作不会调用底层播放器的上一曲接口,返回false底层会调用播放器的上一曲接口,,投屏用到 |
6、语音控制
媒体中心语音控制接口,声明支持的语音语义,以及处理语音控制的回调
fun declareVrSemanticsCapability(channelInfo: MCVrChannelInfo?,vrSemanticCallback: VrSemanticCallback)
参数说明:
参数 | 说明 |
---|---|
channelInfo | MCVrChannelInfo类型,具体字段: mediaPackageName: 应用包名 mediaVersion: 应用版本 mediaDescription: 应用描述 channelDataType: 通道类型,一般设置为0 semantics: IntArray 支持的语义数组,MCSemanticsType.CONTROL_PLAY等 |
vrSemanticCallback | 语音的回调,具体的实现可参考媒体中心接入文档 |
7、播放状态保持
媒体中心的状态保持功能可实现应用的自启动(通过媒体中心拉起),首先在开始播放的时候需要在mediacenterdata中设置recoveryIntent;
示例:
val intent = Intent()intent.setPackage("com.max.example")intent.action = "com.max.example.action.RecoverService"intent.putExtra("type", "StateRecover")
后面在车机重启后,通过如下接口获取之前的播放状态:
fun getRecoveryPlaybackInfo (infoCallback: Consumer<MCPlaybackInfo?>)
其中MCPlaybackInfo
类型和媒体中心中的MusicPlaybackInfo
对应,通过其中的包名可以判断上一次是否自己播放然后更新媒体中心到迷你播放器,实现重启播放恢复的功能。
8、自定义通道
1)媒体中心通道
媒体中心通道用于更新Mini播放器和PSD状态
接口:FlexMediaController.sendCustomAction(action: Int, bundle: Bundle? = null)
- 更新歌词:
val bd = Bundle()bd.putString(Constants.KEY_LYRIC_STRING, "hello lyric")mediaController?.sendCustomAction(Constants.ACTION_UPDATE_LYRIC, bd)
- 更新播放状态:
用于在非播放状态下强制更新媒体信息到媒体中心。
mediaController?.sendCustomAction(Constants.ACTION_UPDATE_MEDIACENTER, null)
2)远程MediaSession通道
远程Mediasession主要用于更新RSD的信息。
Androidx原生接口:MediaController.sendCustomCommand(command: SessionCommand, bundle: Bundle)
- 设置歌词:
val bd = Bundle()bd.putString("lyrics", lyric)bd.putString("lyrics_tr", lyricTr) //英文歌词it.sendCustomCommand(SessionCommand(Constants.COMMAND_SET_SESSION_EXTRA,Bundle.EMPTY), bd)
- 设置试看点:
val bd = Bundle()bd.putBoolean("isCanTrail", isCanTrail)//true试听歌曲,false非试听歌曲bd.putLong("trail_start", start)bd.putLong("trail_end", end)it.sendCustomCommand(SessionCommand(Constants.COMMAND_SET_SESSION_EXTRA,Bundle.EMPTY), bd)
9、更多功能使用原生Player/MediaController接口
有其他更多播放场景的需求,可以通过FlexSimplePlayer/FlexMediaController/player
直接拿到media3的原始player对象实现。
注意事项
- Media3要求工程的compileSDK>=34,这个改动会影响编译过程,不影响运行时。可能会涉及少量系统接口参数适配否则编译会报错,targetSDK建议不动;
- Player的接口调用在主线程进行,对应的状态listener回调也会在主线程中(需要在同一个线程中,否则会报异常);
- startPlay()和stopPlay()调用时机需要匹配,比如在onCreateView中调用startPlay() 在onDestoryView中调用stopPlay(),或者在startPlay()之前先调用stopPlay();
- 全屏的视频播放,activity的
decorView.windowSystemUiVisibility
需要设置View.SYSTEM_UI_FLAG_FULLSCREEN
,这样行车娱乐限制的弹框会根据全屏的状态隐藏状态栏和docker栏; - 当前版本还不支持mediasession service多进程;
参考Demo
uniteplayerdemo(视频)
音频类可参考杜比播放器和网易云音乐APP等应用,附网易云APP的播放架构:
遗留问题
1、电话中播放控制还未在框架中实现,需要应用来处理;
相关文章:
车载音视频App框架设计
简介 统一播放器提供媒体播放一致性的交互和视觉体验,减少各个媒体应用和场景独自开发的重复工作量,实现媒体播放链路的一致性,减少碎片化的Bug。本文面向应用开发者介绍如何快速接入媒体播放器。 主要功能: 新设计的统一播放U…...
StarRocks on AWS Graviton3,实现 50% 以上性价比提升
在数据时代,企业拥有前所未有的大量数据资产,但如何从海量数据中发掘价值成为挑战。数据分析凭借强大的分析能力,可从不同维度挖掘数据中蕴含的见解和规律,为企业战略决策提供依据。数据分析在营销、风险管控、产品优化等领域发挥…...
VUE中setup()
在Vue中,setup() 函数是Vue 3.0及更高版本引入的一个重要特性,它是Composition API的入口点。setup() 函数用于初始化组件的状态和逻辑,包括定义响应式数据、方法和生命周期钩子。以下是关于setup() 函数的详细解释: 1. 作用与特…...
【单元测试】SpringBoot
【单元测试】SpringBoot 1. 为什么单元测试很重要?‼️ 从前,有一个名叫小明的程序员,他非常聪明,但有一个致命的缺点:懒惰。小明的代码写得又快又好,但他总觉得单元测试是一件麻烦事,觉得代码…...
分布式搜索引擎ES-elasticsearch入门
1.分布式搜索引擎:luceneVS Solr VS Elasticsearch 什么是分布式搜索引擎 搜索引擎:数据源:数据库或者爬虫资源 分布式存储与搜索:多个节点组成的服务,提高扩展性(扩展成集群) 使用搜索引擎为搜索提供服务。可以从海量…...
TCP三次握手与四次挥手详解
1.什么是TCP TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,属于互联网协议族(TCP/IP)的一部分。TCP 提供可靠的、顺序的、无差错的数据传输服务&…...
【Windows】操作系统之任务管理器(第一篇)
一、操作系统简介 Windows操作系统是由微软公司(Microsoft)开发的一款图形操作系统,它以其强大的功能和广泛的用户基础,成为了目前世界上用户使用最多、兼容性最强的操作系统之一。以下是关于Windows操作系统的详细介绍ÿ…...
图同构的必要条件
来源:离散数学...
Django获取request请求中的参数
支持 post put json_str request.body # 属性获取最原始的请求体数据 json_dict json.loads(json_str)# 将原始数据转成字典格式 json_dict.get("key", "默认值") # 获取数据参考 https://blog.csdn.net/user_san/article/details/109654028...
kotlin compose 实现应用内多语言切换(不重新打开App)
1. 示例图 2.具体实现 如何实现上述示例,且不需要重新打开App ①自定义 MainApplication 实现 Application ,定义两个变量: class MainApplication : Application() { object GlobalDpData { var language: String = "" var defaultLanguage: Strin…...
记录些MySQL题集(16)
MySQL 存储过程与触发器 一、初识MySQL的存储过程 Stored Procedure存储过程是数据库系统中一个十分重要的功能,使用存储过程可以大幅度缩短大SQL的响应时间,同时也可以提高数据库编程的灵活性。 存储过程是一组为了完成特定功能的SQL语句集合&#x…...
【算法基础】Dijkstra 算法
定义: g [ i ] [ j ] g[i][j] g[i][j] 表示 v i v_i vi 到 $v_j $的边权重,如果没有连接,则 g [ i ] [ j ] ∞ g[i][j] \infty g[i][j]∞ d i s [ i ] dis[i] dis[i] 表示 v k v_k vk 到节点 v i v_i vi 的最短长度, …...
使用 Flask 3 搭建问答平台(三):注册页面模板渲染
前言 前端文件下载 链接https://pan.baidu.com/s/1Ju5hhhhy5pcUMM7VS3S5YA?pwd6666%C2%A0 知识点 1. 在路由中渲染前端页面 2. 使用 JinJa 2 模板实现前端代码复用 一、auth.py from flask import render_templatebp.route(/register, methods[GET]) def register():re…...
pycharm如何debug for循环里面的错误值
一般debug时,在for循环里面的话,需要自己一步一步点。如果循环几百次那种就比较麻烦。此时可以采用try except的方式来解决 例子如下 #ptyhon debug for循环的代码 num[1,2,3,s,4] ans0 for i in num:try:ansiexcept:print(错误) print(ans) 结果如下&a…...
解决网页中的 video 标签在移动端浏览器(如百度访问网页)视频脱离文档流播放问题
问题现象 部分浏览器视频脱离文档流,滚动时,视频是悬浮出来,在顶部播放 解决方案 添加下列属性,可解决大部分浏览器的脱离文档流的问题 <videowebkit-playsinline""playsInlinex5-playsinlinet7-video-player-t…...
.Net--CLS,CTS,CLI,BCL,FCL
1.什么是CLS? 所以.NET专门为此参考每种语言(例如C# ,VB,F#)并找出了语言间的共性,然后定义了一组规则,开发者都遵守这个规则来编码,那么代码就能被任意.NET平台支持的语言所通用。 而与其说是规则&#x…...
Stable Diffusion:质量高画风清新细节丰富的二次元大模型二次元插图
今天和大家分享一个基于Pony模型训练的二次元模型:二次元插图。关于该模型有4个不同的分支版本。 1.5版本:loar模型,推荐底模型niji-动漫二次元4.5。 xl版本:SDXL模型版本 mix版本:光影减弱,减少SDXL版本…...
数读MEME之争:以太坊获更高价值共识,抢占热点成Solana流量密码
在当前显著的加密牛市中,以太坊和Solana之间的竞争不仅在币价表现上显而易见,生态发展方面也备受关注。特别是在这轮MEME行情中,双方阵营的MEME代币呈现出不同的特点和趋势。 市场表现对比 以太坊的优势: 市场份额和认可度更高&…...
python的with语句
1.with语句的作用 在 Python 中,with 语句用于创建一个上下文管理器,以更简洁和安全的方式管理资源。 其主要优点是可以确保在代码块执行完毕后,相关资源能够被正确释放或清理,即使在代码块内部发生了异常。 以下是一个使用 with…...
Selenium原理深度解析
在自动化测试领域,Selenium无疑是最受欢迎和广泛使用的工具之一。它支持多种浏览器和操作系统,为开发人员和测试人员提供了强大的自动化测试解决方案。本文将深入探讨Selenium的工作原理,包括其架构、核心组件、执行流程以及它在自动化测试中…...
算法复杂度<数据结构 C版>
什么是算法复杂度? 简单来说算法复杂度是用来衡量一个算法的优劣的,一个程序在运行时,对运行时间和运行空间有要求,即时间复杂度和空间复杂度。 目录 什么是算法复杂度? 大O的渐近表达式 时间复杂度示例 空间复杂度…...
【XSS】
文章目录 0x01 简介0x02 XSS Payload用法XSS攻击平台及调试JavaScript 0x03 XSS绕过XSS漏洞防御策略 跨站脚本攻击,Cross Site Script。(重点在于脚本script) 有关XSS可以造成的 危害,见 0x02 XSS Payload用法 分类 反射型、存储…...
Go网络编程-RPC程序设计
gRPC 通信 RPC 介绍 RPC, Remote Procedure Call,远程过程调用。与 HTTP 一致,也是应用层协议。该协议的目标是实现:调用远程过程(方法、函数)就如调用本地方法一致。 如图所示: 说明: Servi…...
Linux 性能优化:轻松入门
文章目录 前言一、磁盘性能优化1、 磁盘 RAID 模式选择2、文件系统优化 二、优化 CPU1、性能监控 :2、进程优先级调整 :3、进程与 CPU 绑定 : 三、优化内存四、网络性能优化1、调整 TCP 缓冲区大小2、修改系统级别的文件描述符的数量3、调整 …...
C++相关概念和易错语法(22)(final、纯虚函数、继承多态难点)
1.final final在继承和多态中都可以使用,在继承中是指不想将自己被继承,在多态中是指不想该函数被重写,比较简单,下面是一些使用例子。 2.纯虚函数 当我们需要抽象一个类的时候,我们就需要用到纯虚函数。所谓抽象的类…...
状态管理的艺术:探索Flutter的Provider库
状态管理的艺术:探索Flutter的Provider库 前言 上一篇文章中,我们详细介绍了 Flutter 应用中的状态管理,以及 StatefulWidget 和 setState 的使用。 本篇我们继续介绍另一个实现状态管理的方式:Provider。 Provider优缺点 基…...
玩转HarmonyOS NEXT之IM应用首页布局
本文从目前流行的垂类市场中,选择即时通讯应用作为典型案例详细介绍HarmonyOS NEXT的各类布局在实际开发中的综合应用。即时通讯应用的核心功能为用户交互,主要包含对话聊天、通讯录,社交圈等交互功能。 应用首页 创建一个包含一列的栅格布…...
GPT-4o大语言模型优化、本地私有化部署、从0-1搭建、智能体构建
原文链接:GPT-4o大语言模型优化、本地私有化部署、从0-1搭建、智能体构建https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247608565&idx3&snd4e9d447efd82e8dd8192f7573886dab&chksmfa826912cdf5e00414e01626b52bab83a96199a6bf69cbbef7f7fe…...
记录些MySQL题集(4)
1、数据库的三范式是什么? 第一范式:列不可再分 第二范式:在第一范式的基础上,要求数据库表中的所有非主键列完全依赖于主键,而不是仅依赖于主键的一部分 第三范式:满足第二范式的基础上,所有…...
pdf提取其中一页怎么操作?提取PDF其中一页的方法
pdf提取其中一页怎么操作?需要从一个PDF文件中提取特定页码的操作通常是在处理文档时常见的需求。这种操作允许用户选择性地获取所需的信息,而不必操作整个文档。通过选择性提取页面,你可以更高效地管理和利用PDF文件的内容,无论是…...
要制作自己的网站需要什么材料/网站统计数据分析
原创不易,转载前请注明博主的链接地址:Blessy_Zhu https://blog.csdn.net/weixin_42555080 一 从机器学习到深度学习 我们知道,Machine Learning分为两大派别:频率派和贝叶斯派;前者逐渐发展为统计学习,…...
哪个网站可以做1040/排名优化公司口碑哪家好
转载于:https://blog.51cto.com/williamliuwen/1686493...
b2b电子商务网站分类/seo是哪个英文的简写
引言概率密度期望和协方差 Expectations and covariances1加权平均值2 多变量权重3 条件期望4 函数方差5 协方差 Bayesian Probability5高斯分布重回多项式拟合1理解误差函数2 理解规则化 贝叶斯曲线拟合 主要讲解了贝叶斯概率与统计派概率的不同。概率论,决策论&am…...
java 框架用来做网站/最新军事头条
项目中原始数据都是DWG格式,里面只有两个层,一个0层,一个TX层,0层存储了图廓信息,所有其他要素信息全部存在TX层中,包括房屋,植被,道路,水系,独立地物等等。没…...
佛山网站建设no.1/千万不要做手游推广员
摘要 腾兴网为您分享:PHP定时执行程序脚本的例子总结,中邮网院,智宽生活,指南针,弈客围棋等软件知识,以及包牛牛,幼儿园报名表,药品营销策划方案,excel乱码,家年华&#…...
网站开发接单平台/竞价培训
作用域闭包递归 (自己调自己) 简单闭包 function parent() {var x parentfunction son() {var x sonreturn x}return son() } parent() //son闭包写法: /*写法一*/ function parent() {var x parentreturn function son() {var x …...