1

私はたくさん試しました、今私はあなたの助けが必要です。私がやりたいことは次のとおりです。Blackberryアプリが起動すると、[はい/いいえ]ダイアログが表示されます。ユーザーが「はい」を選択した場合は、何かを実行してから起動を続行します。ユーザーが「いいえ」を選択した場合は、アプリを終了します。

「はい」を選択すると振動し、その後音が聞こえるSSCCEを作成しました。もちろん、Alert.vibrate()が呼び出された後もコードが継続し、バイブレーションが終了するのを待たないことは知っています。とにかく、それは単なる例です。サウンドが再生される前に、vibrate()の呼び出しが最初に来て、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");
}

}

そこで、wait()呼び出しの周りに同期ブロックを配置しました。これを読んだので、wait()を呼び出すときにオブジェクトを同期する必要があります。しかし、今ではアプリは何も表示しません。mainメソッドを実行しますが、どこかで停止します。シミュレーターでは、非常に奇妙なことが起こります。シミュレーターがまだ起動中で、ディスプレイに「デバッガーの接続」と書かれている場合、アプリのmainメソッドが呼び出されます。さて、これが同期ブロックを備えた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

4

2 に答える 2

1

代わりにinvokeAndWaitを使用してください。

private void showDialog(final Dialog d)
{

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

}
于 2012-05-16T14:29:24.947 に答える
1

こんにちは私はついにここのブラックベリーフォーラムで答えを得ました:http ://supportforums.blackberry.com/t5/Java-Development/Startup-YES-NO-Dialog-should-stop-the-launchign-process-of-the/ mp / 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));

        }

    }

}

双方の素晴らしいサポートに感謝します。

于 2012-05-21T07:39:08.400 に答える