【问题标题】:Codename One stop() method: why don't we keep Dialog?代号 One stop() 方法:我们为什么不保留 Dialog?
【发布时间】:2020-08-22 23:21:00
【问题描述】:

默认的代号一种方法是:

public void stop() {
        current = getCurrentForm();
        if (current instanceof Dialog) {
            ((Dialog) current).dispose();
            current = getCurrentForm();
        }
    }

真的有必要dispose一个Dialog吗?为什么? 去掉Dialog相关代码的优缺点?

【问题讨论】:

    标签: codenameone


    【解决方案1】:

    start() 被调用来恢复应用程序。因此,如果它被最小化,stop() 将被调用并处理对话框。假设它没有这样做...start() 将再次被调用,对话框将再次显示。

    对话框的show() 方法被阻塞。因此,它将停止当前的回调并有效地破坏整个恢复过程。

    作为替代方案,我们过去曾尝试检查这是否是关于恢复的对话框并使用showModless(),但这与一些端口代码存在问题,该代码也会在当前Form 上调用show()。唯一可行的解​​决方案是将对话框实例保存为特殊情况并处理它。然后在start() 中用callSerially() 重新显示它。

    【讨论】:

    • 不幸的是 «[...] 将对话框实例保存为特殊情况并处理它。然后在 start()» 中使用 callSerially() 重新显示它仅适用于模拟器和 Android,但不适用于 iPhone。在显示当前表单后,即使使用 UITimer,我也尝试再次显示对话框,但它在 iOS 上不起作用。
    • iOS 是我们拥有这个东西的主要原因之一。它的回调逻辑确实更难。尝试使用 showModless() 而不是 show() 重新显示它。在callSerially()内。
    • 它不工作。问题是,在 iOS 上,如果在 stop() 内部,我将 Dialog 保存在 currentDialog 变量中,然后我调用 dispose,当调用 start() 代码时,currentDialog 变量已变为 null我不知道的原因。
    • 我不认为我们可以使 currentDialog 变量为空而不使 currentForm 变量为空。可能你没有为当前表单赋值,所以正确的代码块没有执行
    • 已解决。我用完整的工作测试用例添加了答案stackoverflow.com/a/63537825/1277576
    【解决方案2】:

    由于某种我不知道的原因,我之前的尝试失败了。我终于找到了一个完美解决问题的代码。我在模拟器中成功测试了它,在 Android 10 和 iOS 13 上。它基于 Shai 的回复https://stackoverflow.com/a/63321677/1277576

    public class MyApplication {
    
        private Form current;
        private Resources theme;
        private Dialog toBeRestored;
    
        public void init(Object context) {
            // use two network threads instead of one
            updateNetworkThreadCount(2);
    
            theme = UIManager.initFirstTheme("/theme");
    
            // Enable Toolbar on all Forms by default
            Toolbar.setGlobalToolbar(true);
    
            // Pro only feature
            Log.bindCrashProtection(true);
    
            addNetworkErrorListener(err -> {
                // prevent the event from propagating
                err.consume();
                if (err.getError() != null) {
                    Log.e(err.getError());
                }
                Log.sendLogAsync();
                Dialog.show("Connection Error", "There was a networking error in the connection to " + err.getConnectionRequest().getUrl(), "OK", null);
            });
        }
    
        public void start() {
            if (current != null) {
                current.show();
                if (toBeRestored != null) {
                    CN.callSerially(() -> toBeRestored.show());
                }
                return;
            }
            Form hi = new Form("Persistent Dialog", BoxLayout.y());
            Button button = new Button("Open Dialog");
            hi.add(button);
            hi.show();
    
            button.addActionListener(l -> {
                Container dialogBody = new Container(BoxLayout.y());
                dialogBody.add(new SpanLabel("Dialog Body"));
                Dialog d = new Dialog(new BorderLayout()){
                    @Override
                    public void dispose() {
                        toBeRestored = this;
                        super.dispose();
                    };
                    
                    @Override
                    public void show() {
                        toBeRestored = null;
                        super.show();
                    };
                };
                d.setDisposeWhenPointerOutOfBounds(false);
                d.add(BorderLayout.CENTER, dialogBody);
                Button okBtn = new Button("OK");
                d.add(BorderLayout.SOUTH, FlowLayout.encloseCenter(okBtn));
                
                okBtn.addActionListener(ll -> {
                    d.dispose();
                });
                
                d.show();
            });
        }
    
        public void stop() {
            current = getCurrentForm();
            if (current instanceof Dialog) {
                ((Dialog) current).dispose();
                current = getCurrentForm();
            }
        }
    
        public void destroy() {
        }
    
    }
    

    【讨论】:

    • 在这段代码中,每次你显示对话框(即使没有最小化)它都会被恢复。您应该在stop() 方法中设置对话框
    猜你喜欢
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 2012-05-05
    • 2015-12-08
    • 2018-05-11
    • 1970-01-01
    • 2013-02-02
    相关资源
    最近更新 更多