我尝试了很多,现在我需要你的帮助。我想做的是:当黑莓应用程序启动时,会弹出一个是/否对话框。如果用户选择“是”,请执行某些操作,然后继续启动。如果用户选择“否”退出应用程序。
我写了一个 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();
}
});
}
}
好的,其他一些 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() 时对象必须是同步的。但现在该应用程序什么也没显示。它运行主要方法,但在某处停止。在模拟器中发生了非常奇怪的事情:当模拟器仍在启动中并且显示器上写着“调试器附加”时,应用程序的主方法被调用。好吧,这里是带同步块的 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");
}
}
谢谢你的帮助。
哈弗布鲁斯