HarmonyOS 鸿蒙Next关于emit,udpsocket, OnPageShw() 函数无法给MyTimer的BeatString赋值的问题
HarmonyOS 鸿蒙Next关于emit,udpsocket, OnPageShw() 函数无法给MyTimer的BeatString赋值的问题
我写了一个Timer,利用timer通知下位机页码,包括设置下位机指令。一个页面计划一般只需要执行两步,就是第四步和第三步UDP指令。其他五步是设置页面的动作。udpskt里面emit事件。计时器里面发送udp指令,emitter的回调函数根据当前的步骤ID和页码确定做什么动作。
import { udpSkt } from ‘…/Model/udp_Socket’;
import Logger from ‘…/common/utils/Logger’
const TAG="[MY_TIMER]"
export class MyTimer {
public static heartBeatingTimer = -1;
public static stepID:number=0;
public static Page:number=0;
public static udpIdle:boolean=false;
public static BeatString:string="";
private static duraion=2000;
static startHeartBeating() {
this.heartBeatingTimer = setInterval(this.callback, this.duraion);
}
private static callback=(()=>
{
if (MyTimer.udpIdle == true)
{
switch (MyTimer.stepID)
{
case 2: //查AP
MyTimer.BeatString = “A=?”;
udpSkt.sendMsg(MyTimer.BeatString);
MyTimer.udpIdle = false;
Logger.info(TAG, “BeatString=” + MyTimer.BeatString)
break;
case 3:
udpSkt.sendMsg(MyTimer.BeatString); //WF=? or ?D
MyTimer.udpIdle = false;
Logger.info(TAG, “BeatString=” + MyTimer.BeatString)
break;
case 4:
udpSkt.sendMsg(MyTimer.BeatString);
MyTimer.udpIdle = false;
Logger.info(TAG, “BeatString=” + MyTimer.BeatString)
break;
case 5: // 检查数据
MyTimer.BeatString = “Prog=?”
udpSkt.sendMsg(MyTimer.BeatString);
MyTimer.udpIdle = false;
Logger.info(TAG, “BeatString=” + MyTimer.BeatString)
break;
case 6: // 请求数据
MyTimer.BeatString = “FetchData”;
udpSkt.sendMsg(MyTimer.BeatString);
MyTimer.udpIdle = false;
Logger.info(TAG, “BeatString=” + MyTimer.BeatString)
break;
case 7: //关闭连接
MyTimer.BeatString = “WF=off”;
udpSkt.sendMsg(MyTimer.BeatString);
MyTimer.udpIdle = false;
Logger.info(TAG, “BeatString=” + MyTimer.BeatString)
break;
}
}
});
}
计划每个页面的onPageShow()设置每个页面第四步udp指令。在emitter的回调函数中,再根据页面设置每个页面第三步的udp指令。
另外,在一个页面,使用
beatingEvent = { eventId: AppEvent.beatEvent };
在AboutAppear()中加载
emitter.on(this.beatingEvent, this.beatingCallBack);
以下是心跳包回调函数:
beatingCallBack=((eventData)=>
{
Logger.info(TAG,“stepID=”+${MyTimer.stepID}
+",Beating string:"+MyTimer.BeatString );
if( MyTimer.stepID==1)
{
this.udpReady = eventData.data.udpReady;
MyTimer.stepID=2;
}
if( MyTimer.stepID==2)
{
MyTimer.udpIdle = eventData.data.udpIdle;
this.udpIdle=eventData.data.udpIdle;
this.APReady = eventData.data.APReady;
if( MyTimer.udpIdle==true && this.APReady ==true ) MyTimer.stepID = 3; //正常心跳
}
if( MyTimer.stepID==3) //正常心跳
{
MyTimer.BeatString=“WF=?”
if( MyTimer.Page===2 ) MyTimer.BeatString="?D"
MyTimer.udpIdle = eventData.data.udpIdle;
}
if( MyTimer.stepID==4) //P=0101 tx:?O ->uart Rx:WF=on,OK 开始获取数据 写页面数据
{
MyTimer.Page=eventData.data.page;
MyTimer.udpIdle = eventData.data.udpIdle;
if( MyTimer.Page===1 ) MyTimer.stepID = 5;
if( MyTimer.Page===3 ) MyTimer.stepID = 3;
if( MyTimer.Page===2 ) MyTimer.stepID = 3;
}
if( MyTimer.stepID==5) //检查进度
{
let progress=eventData.data.progress;
this.lpaProcess = progress;
if (progress === 80) MyTimer.stepID=6;
Logger.info(TAG,“lpaProcess=”+progress.toString())
MyTimer.udpIdle = eventData.data.udpIdle;
this.udpIdle=MyTimer.udpIdle;
}
if( MyTimer.stepID==6) // 请求数据
{
let progress=eventData.data.progress;
this.lpaProcess = progress;
if (progress == 100) {
this.fatchSuccess = true;
this.lpaStateMsg = “液相仪数据传输完成”;
MyTimer.udpIdle = eventData.data.udpIdle;
MyTimer.stepID = 3;
}
以上动作,第3页面可以成功,但是第2页面的第四步udp指令没有设置成功,结果第2页第三步的udp指令就无法正常切换。
因为是工业项目,无法使用更高级别的SDK,目前这些程序都是基于SDK9 .
请有经验的同学指导解决方案。
在HarmonyOS鸿蒙Next的开发环境中,遇到emit
、udpsocket
以及OnPageShw()
函数无法给MyTimer
的BeatString
赋值的问题,这通常涉及到多线程或异步编程中的数据共享与同步问题。
-
emit:如果
emit
用于事件触发,并尝试在非UI线程更新UI控件或全局变量,需确保使用线程安全的方式。考虑使用Handler或LiveData等机制在UI线程更新数据。 -
udpsocket:UDP通信通常运行在后台线程,接收到的数据需通过适当机制(如消息队列、回调等)安全地传递给UI线程或更新全局变量。
-
OnPageShw():该函数可能是页面显示时的回调,如果它试图访问或修改由其他线程(如
udpsocket
线程)管理的数据,同样需要确保线程安全。
解决这类问题,通常要检查数据访问的同步机制,确保所有线程对共享数据的访问都是安全的。可以使用互斥锁(Mutex)、信号量(Semaphore)或其他同步原语来管理对共享资源的访问。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。