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

Android集成科大讯飞语音识别与语音唤醒简易封装

目录

一、语音唤醒部分

1、首先在科大讯飞官网注册开发者账号

2、配置唤醒词然后下载sdk

3、选择对应功能下载

4、语音唤醒lib包全部复制到工程目录下

5、把语音唤醒词文件复制到工程的assets目录

6、复制对应权限到AndroidManifest.xml中

7、唤醒工具类封装

二、语音识别

1、工具类

2、使用


一、语音唤醒部分

1、首先在科大讯飞官网注册开发者账号

控制台-讯飞开放平台

2、配置唤醒词然后下载sdk

3、选择对应功能下载

4、语音唤醒lib包全部复制到工程目录下

5、把语音唤醒词文件复制到工程的assets目录

6、复制对应权限到AndroidManifest.xml中

    <uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><!-- App 需要使用的部分权限 --><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- 科大讯飞 --><uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"tools:ignore="ProtectedPermissions" /><uses-permissionandroid:name="android.permission.READ_PRIVILEGED_PHONE_STATE"tools:ignore="ProtectedPermissions" /><uses-permissionandroid:name="android.permission.MANAGE_EXTERNAL_STORAGE"tools:ignore="ProtectedPermissions" /><uses-permissionandroid:name="android.permission.READ_PHONE_NUMBERS"tools:ignore="ProtectedPermissions" />

7、唤醒工具类封装

 其中IflytekAPP_id为科大讯飞平台的应用id


public abstract class WakeUpUtil {private static AutoTouch autoTouch = new AutoTouch();//自动点击屏幕/*** 唤醒的回调*/public abstract void wakeUp(String resultString);// Log标签private static final String TAG = "WakeUpUtil";// 上下文private static Context mContext;// 语音唤醒对象private VoiceWakeuper mIvw;//唤醒门限值//门限值越高,则要求匹配度越高,才能唤醒//值范围:[0,3000]//默认值:1450private static int curThresh = 1450;public WakeUpUtil(Context context) {initKedaXun(context);mContext = context;// 初始化唤醒对象mIvw = VoiceWakeuper.createWakeuper(context, null);Log.d("initLogData", "===进入唤醒工具类====");}/*** 获取唤醒词功能** @return 返回文件位置*/private static String getResource() {final String resPath = ResourceUtil.generateResourcePath(mContext, RESOURCE_TYPE.assets, "ivw/" + "cf22564a" + ".jet");return resPath;}/*** 唤醒*/public void wake() {Log.d("initLogData", "===进入唤醒工具类====");// 非空判断,防止因空指针使程序崩溃VoiceWakeuper mIvw = VoiceWakeuper.getWakeuper();if (mIvw != null) {// textView.setText(resultString);// 清空参数mIvw.setParameter(SpeechConstant.PARAMS, null);// 设置唤醒资源路径mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource());// 唤醒门限值,根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:" + curThresh);// 设置唤醒模式mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup");// 设置持续进行唤醒mIvw.setParameter(SpeechConstant.KEEP_ALIVE, "1");mIvw.startListening(mWakeuperListener);Log.d("initLogData", "====唤醒====");} else {Log.d("initLogData", "===唤醒未初始化11====");
//            Toast.makeText(mContext, "唤醒未初始化1", Toast.LENGTH_SHORT).show();}}public void stopWake() {mIvw = VoiceWakeuper.getWakeuper();if (mIvw != null) {mIvw.stopListening();} else {Log.d("initLogData", "===唤醒未初始化222====");
//            Toast.makeText(mContext, "唤醒未初始化2", Toast.LENGTH_SHORT).show();}}String resultString = "";private WakeuperListener mWakeuperListener = new WakeuperListener() {@Overridepublic void onResult(WakeuperResult result) {try {String text = result.getResultString();JSONObject object;object = new JSONObject(text);StringBuffer buffer = new StringBuffer();buffer.append("【RAW】 " + text);buffer.append("\n");buffer.append("【操作类型】" + object.optString("sst"));buffer.append("\n");buffer.append("【唤醒词id】" + object.optString("id"));buffer.append("\n");buffer.append("【得分】" + object.optString("score"));buffer.append("\n");buffer.append("【前端点】" + object.optString("bos"));buffer.append("\n");buffer.append("【尾端点】" + object.optString("eos"));resultString = buffer.toString();stopWake();autoTouch.autoClickPos( 0.1, 0.1);wakeUp(resultString);
//                MyEventManager.postMsg("" + resultString, "voicesWakeListener");} catch (JSONException e) {MyEventManager.postMsg("" + "结果解析出错", "voicesWakeListener");resultString = "结果解析出错";wakeUp(resultString);e.printStackTrace();}//            Logger.d("===开始说话==="+resultString);}@Overridepublic void onError(SpeechError error) {MyEventManager.postMsg("" + "唤醒出错", "voicesWakeListener");}@Overridepublic void onBeginOfSpeech() {Log.d("initLogData", "===唤醒onBeginOfSpeech====");}@Overridepublic void onEvent(int eventType, int isLast, int arg2, Bundle obj) {
//            Log.d("initLogData", "===唤醒onEvent===" + eventType);}@Overridepublic void onVolumeChanged(int i) {
//            Log.d("initLogData", "===开始说话==="+i);}};/*** 科大讯飞* 语音sdk* 初始化*/public void initKedaXun(Context context) {// 初始化参数构建StringBuffer param = new StringBuffer();//IflytekAPP_id为我们申请的Appidparam.append("appid=" + context.getString(R.string.IflytekAPP_id));param.append(",");// 设置使用v5+param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);SpeechUtility.createUtility(context, param.toString());Log.d("initLogData", "===在appacation中初始化=====");}}

使用直接调用即可

/*** 科大讯飞* 语音唤醒* 对象*/private WakeUpUtil wakeUpUtil;private void voiceWake() {Log.d("initLogData", "===执行唤醒服务====");wakeUpUtil = new WakeUpUtil(this) {@Overridepublic void wakeUp(String result) {MyEventManager.postMsg("" + "唤醒成功", "voicesWakeListener");Log.d("initLogData", "====唤醒成功===========" + result);// 开启唤醒wakeUpUtil.wake();}};wakeUpUtil.wake();}

到此语音唤醒已经集成结束,接下来是语音识别。

二、语音识别

1、工具类


/*** 科大讯飞* 语音识别* 工具类*/
public class KDVoiceRegUtils {private SpeechRecognizer mIat;private RecognizerListener mRecognizerListener;private InitListener mInitListener;private StringBuilder result = new StringBuilder();// 函数调用返回值private int resultCode = 0;/*** 利用AtomicReference*/private static final AtomicReference<KDVoiceRegUtils> INSTANCE = new AtomicReference<KDVoiceRegUtils>();/*** 私有化*/private KDVoiceRegUtils() {}/*** 用CAS确保线程安全*/public static final KDVoiceRegUtils getInstance() {for (; ; ) {KDVoiceRegUtils current = INSTANCE.get();if (current != null) {return current;}current = new KDVoiceRegUtils();if (INSTANCE.compareAndSet(null, current)) {return current;}Log.d("initLogData", "===科大讯飞实例化===大哥大哥==");}}/*** 初始化* 监听*/public void initVoiceRecorgnise(Context ct) {if (mInitListener != null || mRecognizerListener != null) {return;}mInitListener = new InitListener() {@Overridepublic void onInit(int code) {
//            Log.e(TAG, "SpeechRecognizer init() code = " + code);Log.d("initLogData", "===科大讯飞唤醒初始化===" + code);if (code != ErrorCode.SUCCESS) {
//                showToast("初始化失败,错误码:" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");}}};//识别监听mRecognizerListener = new RecognizerListener() {@Overridepublic void onBeginOfSpeech() {// 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入Log.d("initLogData", "=====开始说话======");}@Overridepublic void onError(SpeechError error) {// Tips:// 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
//                Log.d("initLogData", "====错误说话=====" + error.getPlainDescription(true));senVoicesMsg(300, "识别错误 ");//100启动语音识别    200识别成功   300识别错误mIat.stopListening();hideDialog();}@Overridepublic void onEndOfSpeech() {// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入mIat.stopListening();
//                Log.d("initLogData", "=====结束说话======");hideDialog();}@Overridepublic void onResult(RecognizerResult results, boolean isLast) {String text = parseIatResult(results.getResultString());
//                Log.d("initLogData", "==说话==语音识别结果==initVoice==" + text);result.append(text);if (!text.trim().isEmpty() && boxDialog != null) {senVoicesMsg(200, "识别成功");//100启动语音识别    200识别成功   300识别错误boxDialog.showTxtContent(result.toString());senVoicesMsg(200, "" + result.toString());}if (isLast) {result.setLength(0);}}@Overridepublic void onVolumeChanged(int volume, byte[] data) {//showToast("当前正在说话,音量大小:" + volume);if (volume > 0 && boxDialog != null) {boxDialog.showTxtContent("录音中...");}Log.d("initLogData", "===说话==onVolumeChanged:====" + volume);}@Overridepublic void onEvent(int eventType, int arg1, int arg2, Bundle obj) {// 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因// 若使用本地能力,会话id为nullif (SpeechEvent.EVENT_SESSION_ID == eventType) {String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);}}};// 初始化识别无UI识别对象// 使用SpeechRecognizer对象,可根据回调消息自定义界面;mIat = SpeechRecognizer.createRecognizer(ct, mInitListener);if (mIat != null) {setIatParam();//参数配置}}/*** 执行语音* 识别*/public void startVoice(Context context) {senVoicesMsg(100, "启动语音识别");//100启动语音识别    200识别成功   300识别错误if (mIat != null) {showDialog(context);mIat.startListening(mRecognizerListener);}}/*** 科大讯飞* 语音识别* 参数配置*/private void setIatParam() {// 清空参数mIat.setParameter(com.iflytek.cloud.SpeechConstant.PARAMS, null);// 设置听写引擎mIat.setParameter(com.iflytek.cloud.SpeechConstant.ENGINE_TYPE, com.iflytek.cloud.SpeechConstant.TYPE_CLOUD);// 设置返回结果格式mIat.setParameter(com.iflytek.cloud.SpeechConstant.RESULT_TYPE, "json");// 设置语言mIat.setParameter(com.iflytek.cloud.SpeechConstant.LANGUAGE, "zh_cn");// 设置语言区域mIat.setParameter(com.iflytek.cloud.SpeechConstant.ACCENT, "mandarin");// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理mIat.setParameter(com.iflytek.cloud.SpeechConstant.VAD_BOS, "4000");// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音mIat.setParameter(com.iflytek.cloud.SpeechConstant.VAD_EOS, "500");// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点mIat.setParameter(com.iflytek.cloud.SpeechConstant.ASR_PTT, "0");Log.d("initLogData", "==语音是被==初始化成功:====");// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限// 注:AUDIO_FORMAT参数语记需要更新版本才能生效
//        mIatDialog.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
//        mIatDialog.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/MyApplication/" + filename + ".wav");}/*** 语音* 识别* 解析*/public static String parseIatResult(String json) {StringBuffer ret = new StringBuffer();try {JSONTokener tokener = new JSONTokener(json);JSONObject joResult = new JSONObject(tokener);JSONArray words = joResult.getJSONArray("ws");for (int i = 0; i < words.length(); i++) {// 转写结果词,默认使用第一个结果JSONArray items = words.getJSONObject(i).getJSONArray("cw");JSONObject obj = items.getJSONObject(0);ret.append(obj.getString("w"));}} catch (Exception e) {e.printStackTrace();}return ret.toString();}/*** 对话框* getApplicationContext()*/private VoiceDialog boxDialog;private void showDialog(Context context) {View inflate = LayoutInflater.from(context).inflate(R.layout.donghua_layout, null, false);boxDialog = new VoiceDialog(context, inflate, VoiceDialog.LocationView.BOTTOM);boxDialog.show();}/*** 隐藏* 对话框*/private void hideDialog() {if (boxDialog != null) {boxDialog.dismiss();}}/*** 发送语音* 识别消息** @param code* @param conn*/private void senVoicesMsg(int code, String conn) {VoiceRecognizeResult voiceRecognizeResult = new VoiceRecognizeResult();voiceRecognizeResult.setCode(code);//100启动语音识别    200识别成功   300识别错误voiceRecognizeResult.setMsg("" + conn);String std = JSON.toJSONString(voiceRecognizeResult);MyEventManager.postMsg("" + std, "VoiceRecognizeResult");}/*** 科大讯飞* 语音sdk* 初始化*/public void initKedaXun(Context context) {// 初始化参数构建StringBuffer param = new StringBuffer();//IflytekAPP_id为我们申请的Appidparam.append("appid=" + context.getString(R.string.IflytekAPP_id));param.append(",");// 设置使用v5+param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);SpeechUtility.createUtility(context, param.toString());Log.d("initLogData", "===在appacation中初始化=====");}}

2、使用

        KDVoiceRegUtils.getInstance().initKedaXun(mWXSDKInstance.getContext());KDVoiceRegUtils.getInstance().initVoiceRecorgnise(mUniSDKInstance.getContext());//语音识别初始化KDVoiceRegUtils.getInstance().startVoice(mUniSDKInstance.getContext());

注意其实代码还可以优化,由于公司业务需要,封装的不怎么彻底,使用者可在此基础上进一步封装。

相关文章:

Android集成科大讯飞语音识别与语音唤醒简易封装

目录 一、语音唤醒部分 1、首先在科大讯飞官网注册开发者账号 2、配置唤醒词然后下载sdk 3、选择对应功能下载 4、语音唤醒lib包全部复制到工程目录下 5、把语音唤醒词文件复制到工程的assets目录 6、复制对应权限到AndroidManifest.xml中 7、唤醒工具类封装 二、语音识…...

【Linux】telnet命令使用

telnet命令 telnet命令用于使用telnet协议与另一台主机进行通信。如果在没有主机参数的情况下调用telnet&#xff0c;它将进入命令模式&#xff0c;由其提示&#xff08;telnet>&#xff09;指示。在这种模式下&#xff0c;它接受并执行下面列出的命令。如果使用参数调用它…...

VCG 标记使用(BitFlags)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 对于网格的每个单形,我们都有一个称为BitFlags的组件,该组件存储固定大小的32位向量,用于各种需求。管理这些标志的相关类:vcg::tri::UpdateFlags与vcg::tri::UpdateSelection。主要的标记有:删除标记、边界标记…...

Pandas中的Series(第1讲)

Pandas中的Series(第1讲)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔…...

从手工测试进阶中高级测试?如何突破职业瓶颈...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、手工测试如何进…...

【链表Linked List】力扣-114 二叉树展开为链表

目录 题目描述 解题过程 官方题解 题目描述 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应…...

Go (一) 基础部分4 -- 文件处理

一、文件基本介绍 1.1、打开一个文件 基本介绍&#xff1a;打开一个文件用于读取&#xff0c;如果操作成功&#xff0c;返回的文件对象的方法可用于读取文件数据。如果出错&#xff0c;错误底层类型是"*.PathError" func Open(name string) (*File, error) name stri…...

集合03 Collection (List) - Java

List ArrayListArrayList注意事项ArrayList底层操作机制-源码分析&#xff08;重点&#xff09; VectorVector基本介绍 ——Vector和ArrayList比较Vector底层结构和源码分析 LinkedList基本介绍LinkedList的底层结构和操作机制LinkedList的增删改查 ——LinkedList和ArrayList比…...

国产化软件突围!怿星科技eStation产品荣获2023铃轩奖“前瞻优秀奖”

11月11日&#xff0c;2023中国汽车供应链峰会暨第八届铃轩奖颁奖典礼在江苏省昆山市举行。怿星科技凭借eStation产品&#xff0c;荣获2023铃轩奖“前瞻智能座舱类优秀奖”&#xff0c;怿星CEO潘凯受邀出席铃轩奖晚会并代表领奖。 2023铃轩奖“前瞻智能座舱类优秀奖” 铃轩奖&a…...

如何解决Redis热Key问题?

Redis热点key是指访问频率较高的key&#xff0c;当大量的请求集中在一个或少数几个热点key上时&#xff0c;会导致这些key所在的Redis节点的CPU、内存和网络带宽等资源被大量消耗&#xff0c;影响Redis集群的整体性能和稳定性。 热点Key带来的问题 Redis节点负载过高&#xff1…...

react Hooks之useId

当我们在编写React组件时&#xff0c;有时需要为元素生成唯一的ID。这种情况经常出现在表单元素、标签和用于无障碍性的目的上。React提供了一个名为useId的自定义Hook&#xff0c;它可以帮助我们生成唯一的ID。 1、作用&#xff1a; 用于生成一个唯一的 ID。这个 ID 可以用于…...

2023年全球软件开发大会(QCon广州站2023)-核心PPT资料下载

一、峰会简介 本次峰会包含&#xff1a;泛娱乐时代的边缘计算与通讯、稳定性即生命线、下一代软件架构、出海的思考、现代数据架构、AGI 与 AIGC 落地、大前端技术探索、编程语言实战、DevOps vs 平台工程、新型数据库、AIGC 浪潮下的企业出海、AIGC 浪潮下的效能智能化、数据…...

MicroSD 卡 使用读卡器 读取速度测试

设备 - - 电脑为m.2固态硬盘 usb口为USB3.2 gen2接口(即支持1GB/s的接口) cpu: amd3600 测试方案1 直接MicroSD卡放入读卡器测试 38MB/s 从sd卡复制到本地C盘 测试方案2 MicroSD卡使用闪迪的SD卡套套上之后一起插入读卡器 76MB/s 从sd卡复制到本地C盘...

Selenium+Unittest+HTMLTestRunner框架更改为Selenium+Pytest+Allure(一)

背景&#xff1a;之前的框架&#xff0c;Selenium是3.x版本&#xff0c;现在更新到4.15版本后&#xff0c;一些写法如find_element_by_xxx 不再支持&#xff0c;改为find_element(By.xxx)的方式&#xff0c;同时由于Unittest不如Pytest在执行方面灵活&#xff08;比如只执行冒烟…...

LoRA(Low-Rank Adaptation)

LoRA&#xff08;Low-Rank Adaptation&#xff09; LoRA&#xff08;Low-Rank Adaptation&#xff09;是一种针对深度学习模型的参数调整方法&#xff0c;特别适用于大型预训练模型如GPT-3或BERT。它通过在模型的原有权重上添加低秩&#xff08;low-rank&#xff09;矩阵&…...

【银行测试】第三方支付功能测试点+贷款常问面试题(详细)

前言 1、第三方支付功能测试点 支付流程&#xff1a; 我们在测试一个功能时&#xff0c;需要先了解一下这个逻辑&#xff0c;而订单支付逻辑普遍都会有以下内容&#xff1a; 1&#xff09;创建本地唯一订单号&#xff1b; 2&#xff09;去调用支付&#xff0c;在支付平台生…...

前端:HTML+CSS+JavaScript实现轮播图2

前端&#xff1a;HTMLCSSJavaScript实现轮播图2 1. 和之前版本的区别2. 实现原理3. 针对上述的改进3. 参考代码 1. 和之前版本的区别 之前发布的那篇关于轮播图的文章在这&#xff1a;前端&#xff1a;HTMLCSSJavaScript实现轮播图&#xff0c;只能说存在问题吧&#xff01;比…...

使用条件格式突出显示单元格数据-sdk

使用条件格式突出显示单元格数据 2023 年 12 月 6 日 根据数据值将视觉提示应用于特定单元格、行或列&#xff0c;从而更轻松地识别模式和趋势。 网格中的条件格式允许用户根据单元格或范围包含的数据将视觉样式应用于单元格或范围。它通过以数据驱动的方式突出显示关键值、异常…...

java面试题-Dubbo和zookeeper运行原理

远离八股文&#xff0c;面试大白话&#xff0c;通俗且易懂 看完后试着用自己的话复述出来。有问题请指出&#xff0c;有需要帮助理解的或者遇到的真实面试题不知道怎么总结的也请评论中写出来&#xff0c;大家一起解决。 java面试题汇总-目录-持续更新中 分布式注册中心和服务调…...

XSS漏洞 深度解析 XSS_labs靶场

XSS漏洞 深度解析 XSS_labs靶场 0x01 简介 XSS原名为Cross-site Sciprting(跨站脚本攻击)&#xff0c;因简写与层叠样式表(Cascading style sheets)重名&#xff0c;为了区分所以取名为XSS。 这个漏洞主要存在于HTML页面中进行动态渲染输出的参数中&#xff0c;利用了脚本语…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...