关于鸿蒙任务分发器(多线程)取消任务接口的误区

软盟云智 经验分享 31

关于鸿蒙任务分发器(多线程)取消任务接口的误区

鸿蒙有专门的多线程接口,相比于java的Thread和Runable,更简单且更灵活。文档资料。

接口中有个:

Revocable
取消任务:Revocable是取消一个异步任务的接口。异步任务包括通过 asyncDispatch、delayDispatch、asyncGroupDispatch 派发的任务。如果任务已经在执行中或执行完成,则会返回取消失败。

相信不少人看到这个接口以为是多线程懒人版的福音,以为可以从外部轻松杀死一个线程。但文档中说的很清楚“如果任务已经在执行中或执行完成,则会返回取消失败”,所以线程的结束还是应该从内部自行结束。

我们写个例子来验证一下,这里以异步派发任务asyncDispatch为例子

首先写个简单的布局,布局中就一个按钮,这里就不赘述了,按钮的ID是ohos:id=”$+id:button_ok”。

我们的目标是程序启动后后台任务(线程)开启,点击按钮结束线程。

在MainAbilitySlice的onCreate方法中开启后台任务(线程):

//绑定按钮点击事件
Button button = (Button) findComponentById(ResourceTable.Id_button_ok);
button.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
//用revoked结束线程
boolean revoked = revocable.revoke();
HiLog.info(LABEL, “revoked:%{public}b”, revoked);
}
});

//开启后台任务,是一个10秒的循环
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
revocable = globalTaskDispatcher.asyncDispatch(new Runnable() {
@Override
public void run() {
for (int i=0 ;i < 10;i++){
HiLog.info(LABEL, “async : %d” , i);
try {
sleep(1000);
}catch (Exception e){

}
}
}
});
复制
运行之后不出意外的,取消任务失败了

0900086000300134184.20201216095126.86523331460016843504112994983392.png

结果证明

Revocable并不能从外部杀死一个正在运行的线程,也并不能处理僵尸线程,它的作用就是在任务(一般是延时任务)还没有开始之前取消。

如果要结束一个正在运行的线程,还是要在外部设定一个信号量,通知线程自己结束

Revocable revocable = null;
private volatile boolean SINGLETON = false;

@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);

Button button = (Button) findComponentById(ResourceTable.Id_button_ok);
button.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
//boolean revoked = revocable.revoke();
//HiLog.info(LABEL, “revoked:%{public}b”, revoked);
SINGLETON = true;
HiLog.info(LABEL, “try tu cancel task”😉;
}
});

TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
revocable = globalTaskDispatcher.asyncDispatch(new Runnable() {
@Override
public void run() {
for (int i=0 ;i < 10;i++){
if(SINGLETON){
HiLog.info(LABEL, “async break : %d” , i);
break;
}
HiLog.info(LABEL, “async : %d” , i);
try {
sleep(1000);
}catch (Exception e){

}
}
}
});
}

    回复

    我来回复
    • 暂无回复内容