私はたくさん試しました、今私はあなたの助けが必要です。私がやりたいことは次のとおりです。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