黑莓 - 显示对话框启动,等到对话框关闭(Blackberry - Show Dialog on s

2019-09-17 06:42发布

我尝试了很多,现在我需要你的帮助。 我想要做的是:当黑莓应用程序启动是/否对话框弹出。 如果用户选择“是”,做一些事情,之后继续启动。 如果用户选择“否”退出程序。

我写的,如果你选择“是”之后,你应该听到声音,应振动的SSCCE。 我当然知道,该代码继续Alert.vibrate()被调用后,并没有等待vibraste完成。 无论如何,这只是一个例子。 振动()的调用应该先和dialogClosed()应该被播放的声音之前完全处理。

该SSCCE是我走到这一步。 我试过很多其他的东西。 我敢肯定,这不可能是那么难。 我只是不明白这一点。

这里是:

package TestDialog;

import net.rim.device.api.system.Alert;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.DialogClosedListener;

public class TestDialog extends UiApplication
{

public static short[] SOUND_ALERT = { 523, 200, //C for 200ms
                0, 200, //Pause 200ms
                554, 200, //C# 200ms
                0, 200, //Pause 200ms
                587, 200, //D 200ms
                0, 200, //Pause 200ms
                622, 200         //D# 200ms         
                                  };

/**
 * @param args
 */
public static void main(final String[] args)
{

    final TestDialog test = new TestDialog();
    test.enterEventDispatcher();

}

public TestDialog()
{

    //the dialog
    final Dialog d = new Dialog(Dialog.D_YES_NO, "vibrate?", Dialog.OK, Bitmap.getPredefinedBitmap(Bitmap.QUESTION), Dialog.FIELD_TOP);
    d.setDialogClosedListener(new DialogClosedListener()
    {

        public void dialogClosed(final Dialog dialog, final int choice)
        {
            if (d.getSelectedValue() == Dialog.YES)
            {
                Alert.startVibrate(2000);
                //do something which takes some time
            }
            else
            {
                System.exit(0);
            }

        }
    });

    //show the dialog
    showDialog(d);

    //now wait for the dialog to call notify
    try
    {
        synchronized (this)
        {
            this.wait();
        }
    }
    catch (final Exception e)
    {
        System.out.println(e.getMessage());
    }

    //finally AFTER the dialog has been closed and everything in dialogClosed() has been done, play a sound
    Alert.startAudio(SOUND_ALERT, 100);

}

private void showDialog(final Dialog d)
{

    UiApplication.getUiApplication().invokeLater(new Runnable()
    {
        public void run()
        {
            d.doModal();
            this.notify();
        }
    });

}
}

OK,其他一些SSCCE。 这将启动并显示一个对话框,但随后抛出IllegalMonitorExcpetion:

package TestDialog;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;

public class TestDialog extends UiApplication
{

public static short[] SOUND_ALERT = { 523, 200, //C for 200ms
                0, 200, //Pause 200ms
                554, 200, //C# 200ms
                0, 200, //Pause 200ms
                587, 200, //D 200ms
                0, 200, //Pause 200ms
                622, 200         //D# 200ms         
                                  };

/**
 * @param args
 */
public static void main(final String[] args)
{

    final TestDialog test = new TestDialog();
    test.enterEventDispatcher();

}

public TestDialog()
{

    UiApplication.getUiApplication().invokeLater(new Runnable()
    {
        public void run()
        {
            //the dialog
            final Dialog d = new Dialog(Dialog.D_YES_NO, "vibrate?", Dialog.OK, Bitmap.getPredefinedBitmap(Bitmap.QUESTION), Dialog.FIELD_TOP);

            if (d.doModal() == Dialog.YES)
            {
                System.out.println("selection made yes");
                this.notify();
            }
            else
            {
                System.out.println("selection made no");
                System.exit(0);
            }

        }
    });


        try
        {
            this.wait();
        }
        catch (final Exception e)
        {
            e.printStackTrace();
        }


    //finally AFTER the dialog has been closed and everything in dialogClosed() has been done, play a sound
    System.out.println("done");
}

}

所以我把一个synchronized块周围的wait()调用,因为我读,该对象必须调用wait()时进行同步。 但是,现在的应用程序显示什么。 它运行的主方法,但什么地方停止。 在模拟器很奇怪的事情发生了:当模拟器仍处于启动和“调试器附着”在显示屏上写的,应用程序的主方法被调用。 嗯,这里是用synchronized块SSCCE。 仍然无法正常工作。

package TestDialog;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;

public class TestDialog extends UiApplication
{

public static short[] SOUND_ALERT = { 523, 200, //C for 200ms
                0, 200, //Pause 200ms
                554, 200, //C# 200ms
                0, 200, //Pause 200ms
                587, 200, //D 200ms
                0, 200, //Pause 200ms
                622, 200         //D# 200ms         
                                  };

/**
 * @param args
 */
public static void main(final String[] args)
{

    final TestDialog test = new TestDialog();
    test.enterEventDispatcher();

}

public TestDialog()
{

    UiApplication.getUiApplication().invokeLater(new Runnable()
    {
        public void run()
        {
            //the dialog
            final Dialog d = new Dialog(Dialog.D_YES_NO, "vibrate?", Dialog.OK, Bitmap.getPredefinedBitmap(Bitmap.QUESTION), Dialog.FIELD_TOP);

            if (d.doModal() == Dialog.YES)
            {
                System.out.println("selection made yes");
                this.notify();
            }
            else
            {
                System.out.println("selection made no");
                System.exit(0);
            }

        }
    });

    synchronized (this)
    {
        try
        {
            this.wait();
        }
        catch (final Exception e)
        {
            e.printStackTrace();
        }
    }

    //finally AFTER the dialog has been closed and everything in dialogClosed() has been done, play a sound
    System.out.println("done");
}

}

最后我想利用的忙等待。 仍然没有成功。 对话只是不弹出。 即使在主线程中while循环Thread.sleep代码(1000)UI线程似乎不起作用。 这里是繁忙等待的SSCCE:

    package TestDialog;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;

public class TestDialog extends UiApplication
{
    /**
     * @param args
     */
    public static void main(final String[] args)
    {

        final TestDialog test = new TestDialog();
        test.enterEventDispatcher();

    }

    private volatile boolean _blocked = true;

    public TestDialog()
    {

        UiApplication.getUiApplication().invokeLater(new Runnable()
        {
            public void run()
            {
                //the dialog
                final Dialog d = new Dialog(Dialog.D_YES_NO, "vibrate?", Dialog.OK, Bitmap.getPredefinedBitmap(Bitmap.QUESTION), Dialog.FIELD_TOP);

                if (d.doModal() == Dialog.YES)
                {
                    System.out.println("selection made yes");
                    _blocked = false;
                }
                else
                {
                    System.out.println("selection made no");
                    System.exit(0);
                }

            }
        });

        while (_blocked)
        {
            try
            {
                Thread.sleep(1000);
            }
            catch (final Exception e)
            {
                //safety catch
            }
        }
        finish();

    }

    private void finish()
    {
        System.out.println("done");
    }

}

谢谢你的帮助。

Haferblues

Answer 1:

HI我终于在黑莓论坛答案在这里: http://supportforums.blackberry.com/t5/Java-Development/Startup-YES-NO-Dialog-should-stop-the-launchign-process-of-the/熔点/ 1725085

最终的解决方案,这对我的作品(而且看上去更漂亮,然后我在上面所做的一切)如下:

    package TestDialog;

import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.container.MainScreen;

public class TestDialog extends UiApplication implements Runnable
{
    /**
     * @param args
     */
    public static void main(final String[] args)
    {

        final TestDialog test = new TestDialog();
        test.invokeLater(test);

        test.enterEventDispatcher();

    }

    public TestDialog()
    {

    }

    public void run()
    {

        final int answer = Dialog.ask(Dialog.D_YES_NO, "continue?");
        //        pushGlobalScreen(new Dialog(Dialog.D_YES_NO, "continue?", 0, null, Dialog.GLOBAL_STATUS), 1, TestDialog.GLOBAL_QUEUE | TestDialog.GLOBAL_MODAL);

        if (answer == Dialog.YES)
        {
            System.out.println("user clicked yes");
        }
        else
        {
            System.exit(0);
        }

        pushScreen(new MyScreen("App loaded"));
    }

    class MyScreen extends MainScreen
    {

        public MyScreen(final String msg)
        {

            final LabelField title = new LabelField("First Screen", LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
            setTitle(title);
            this.add(new RichTextField(msg));

        }

    }

}

感谢双方的大力支持。



Answer 2:

使用invokeAndWait而不是invokeLater的。

private void showDialog(final Dialog d)
{

    UiApplication.getUiApplication().invokeAndWait(new Runnable()
    {
        public void run()
        {
            d.doModal();
            this.notify();
        }
    });

}


文章来源: Blackberry - Show Dialog on startup and wait until dialog closes