Android教程 DoEvents弃用和异步对话框(消息框)

从B4A v7.0开始,DoEvents调用将出现以下警告:
不赞成使用DoEvents。这可能导致稳定问题。如果确实需要,请使用睡眠(0)。

DoEvents的目的是允许在主线程繁忙时更新UI。DoEvents与模态对话框实现共享相同的实现,是一个低级实现。它访问进程消息队列并运行一些等待消息。

随着Android的发展,消息队列的处理变得更加复杂和脆弱。
不推荐使用DoEvents的原因如下:

1.它是不稳定问题的主要来源。它可能导致难以调试的崩溃或ANR(应用程序无响应)对话框。注意,对于模式对话框(例如Msgbox和InputList)也是如此。
2.有更好的方法保持主线程空闲。例如,使用异步SQL方法而不是同步方法。
3.它没有做许多开发人员期望它做的事情。因为它只处理与UI相关的消息,所以大多数事件无法从DoEvents调用中引发。
4.现在可以调用Sleep暂停当前sub,并在处理等待消息后恢复。睡眠实施与DoEvents完全不同。它不支持线程。而是在保留子状态的同时释放它。
与DoEvents只处理与UI相关的消息不同,使用Sleep将处理所有消息,并引发其他事件。
(请注意,使用Wait For等待事件比在循环中调用Sleep要好。)

尽管如此,DoEvents仍然存在,现有的应用程序将完全像以前一样工作。

对话框

模态对话框=在对话框关闭之前保持主线程的对话框。

如上所述,模态对话框与DoEvents共享相同的实现。因此,建议切换到新的异步对话框。使用等待这真的是一个简单的改变:

而不是:
B4X码:
Dim res As Int=Msgbox2(“删除?”,“标题”,“是”,“取消”,“否”,Null)如果res=DialogResponse。积极然后End If(结束条件)
您应该使用:
B4X码:
Msgbox2Async(“删除?”,“标题”,“是”,“取消”,“否”,Null,False)等待消息框结果(结果为Int)如果结果=对话框响应。积极然后'...结束如果

等待不支持主线程。相反,它保存当前的子状态并释放它。当用户单击其中一个对话框按钮时,代码将恢复。
其他类似的新方法有:MsgboxAsync、InputListAsync和InputMapAsync。

除了MsgboxAsync之外,新方法还添加了一个新的可取消的参数。如果为真,则可以通过单击返回键或对话框外部来关闭对话框。这是旧方法的默认行为。

由于其他代码可以在异步对话框可见时运行,因此可能会同时出现多个对话框。
如果此情况与应用程序相关,则应在Wait for call:
B4X码:
Dim sf As Object=Msgbox2Async(“删除?”,“标题”,“是”,“取消”,“否”,Null,False)等待(sf)消息框结果(结果为Int)如果结果=对话框响应。积极然后'...End If(结束条件)
这样可以显示多条消息,并正确处理结果事件。

B4A v7.00/7.01中的错误-不应在类中使用异步对话框,因为Result事件将在Activity中而不是类模块中引发。这在下次更新时已修复。
 
上次编辑时间:

星尘

专家
许可用户
长期用户
谢谢你,埃雷尔先生。

考虑到有一些库或类使用DoEvents来等待事件的结果,正如它对类似于MsgBox或其他对话框对象的对象所指出的那样,
当然,必须使用命令等待更新版本7。

我的问题是这个。
将来,您需要为使用wats的版本7或使用DoEvents的早期版本生成库或类吗?
运行wait命令是否需要特定的API?
使用wait命令编译B4A版本7的库可以与以前版本的B4A一起使用吗?
 
上次编辑时间:

星尘

专家
许可用户
长期用户
谢谢
 

依那西普

B4X创始人
工作人员
许可用户
长期用户
上次编辑时间:

小装置

知名会员
许可用户
长期用户
埃雷尔,当你说:
1.可恢复的sub不能返回值。
2.代码流不同。调用Sleep或Wait For等同于从调用者子视角调用Return。

1) 该规则适用于修改参数比如地图或列表,对吗?

2) 是否会更改CustomListView以完全删除“DoEvents”?
(getHeight、getWidth等一些Subs是函数)

3) B4X版本号是否有内置条件变量,因此可以用作:

B4X码:
#如果$VER>6.5...#结束IF#如果$VER=7。。#结束IF#如果$PROD=“B4A”..B4A代码。。#ELSE公司#如果$PROD=“B4I”…B4i代码。。。#结束IF#结束IF

蒂亚
 

依那西普

B4X创始人
工作人员
许可用户
长期用户
1) 您可以在可恢复子中执行任何操作,包括修改列表、映射或全局变量,除了调用Return<value here>。

2) 最新版本的CustomListView中没有DoEvents调用。过去,DoEvents用于立即更改滚动位置。这不再是必需的,因为您可以使用ScrollView。滚动到现在。

3) 产品符号可用:https://www.b4x.com/android/forum/t…mpilation-build-configurations.40746/#content
版本没有内置符号。
 

伊兰

专家
许可用户
长期用户
非常感谢你的这首小诗。这是b4a的一个非常重要的补充。

我有一个小问题。

时间/日期对话框在用户响应之前是否也保持主线程?

如果是,是否有类似的日期和时间对话框解决方案?

谢谢你
 

伊兰

专家
许可用户
长期用户
可恢复子功能真的很棒。我在很多情况下都使用它,效果很好。用csu代替csu可以避免很多头痛。

我只是不理解代码中的某些内容:

B4X码:
Msgbox2Async(“删除?”、“标题”、“是”、“取消”、“否”、Null、False)等待消息框结果(结果为Int)如果结果=对话框响应。肯定然后'...End If(结束条件)

在等待行中,您在代码中说要等待子Msgbox_Result(Result As Int)

所以一开始我手动创建了这个sub并返回了值,但后来我注意到我不需要创建它,但我不知道从哪里返回结果??

它是从这条线路返回的吗?就像将2个sub放在1个sub中,当用户点击msgbox按钮时,它将从该行返回?
 

德雷兹

专家
许可用户
长期用户
你要如何处理这个必须返回值的sub?
b4倍:
子Activity_KeyPress(KeyCode As Int)作为布尔值如果KeyCode=KeyCodes。KEYCODE_BACK然后Dim k As Int=消息框2(……)如果k=对话响应。负,然后返回真End If(结束条件)返回False结束Sub
 

伊兰

专家
许可用户
长期用户
你要如何处理这个必须返回值的sub?
B4X码:
子Activity_KeyPress(KeyCode As Int)作为布尔值如果KeyCode=KeyCodes。然后返回KEYCODE_BACKDim k As Int=消息框2(……)如果k=对话响应。否定然后返回真End If(结束条件)返回False结束Sub

可能是这样的:

B4X码:
私有returnValue为布尔值'...子Activity_KeyPress(KeyCode As Int)作为布尔值如果KeyCode=KeyCodes。然后返回KEYCODE_BACKmsgb(“退出应用程序?”,“退出”)如果returnValue,则返回TrueEnd If(结束条件)返回False结束SubSub msgb(txt为字符串,title为字符串)returnValue=假Dim sf As Object=Msgbox2Async(txt,title,“是”,“取消”,“否”,Null,False)等待(sf)消息框结果(结果为Int)如果结果=对话框响应。肯定然后returnValue=真End If(结束条件)结束Sub
 

依那西普

B4X创始人
工作人员
许可用户
长期用户
你要如何处理这个必须返回值的sub?
此代码更简单,不使用全局变量:
B4X码:
Sub Activity_KeyPress(KeyCode As Int)As Boolean“返回True以使用事件如果KeyCode=KeyCodes。然后返回KEYCODE_BACK应关闭活动返回TrueEnd If(结束条件)返回False结束Sub私有子应关闭活动Dim sf As Object=Msgbox2Async(…)等待(sf)消息框结果(结果为Int)如果结果,则活动。完成结束Sub
 

伊兰

专家
许可用户
长期用户
我这样写代码是因为这是一种返回值的方法。

你要如何处理这个必须返回值的sub?

如果它只执行finishtheapp这样的操作,那么erels解决方案更好,但不幸的是,如果你想返回一个值,我看不出不使用全局变量(来自可恢复的sub)的方法。
 

依那西普

B4X创始人
工作人员
许可用户
长期用户
如果它只执行finishtheapp这样的操作,那么erels解决方案更好,但不幸的是,如果你想返回一个值,我看不出不使用全局变量(来自可恢复的sub)的方法。
无法在Activity_KeyPress事件中显示模式对话框或调用DoEvents。从Android 4.3开始,它会导致低级别崩溃。

因为我知道这个sub主要用于与您发布的代码类似的代码,所以我添加了一个back键的检查,它实际上使用了一个类似于CallSubDelayed的解决方案,然后根据返回值关闭活动。如果您试图在按下的键不是返回键时显示模式对话框,那么它将崩溃。
你可以在这里看到它:https://www.b4x.com/android/help/views.html#activity
重点是异步对话框总是比模式对话框更好(更安全)。

如果不使用全局变量(从可恢复的子变量),您想返回一个我看不到的值。
您不需要全局变量。您需要使用CallSubDelayed返回值。
https://www.b4x.com/android/forum/threads/b4x-resumable-subs-sleep-wait-for.78601/page-3#帖子-506651
 

计算机64

知名会员
许可用户
长期用户
B4A v7.00/7.01中的错误-不应在类中使用异步对话框,因为Result事件将在Activity中而不是类模块中引发。这在下次更新时已修复。

嗨,埃雷尔-我现在正在做的一个项目中正好有这个问题。你知道什么时候发布修复程序吗?

-科林。
 
顶部