我尝试了很多,现在我需要你的帮助。我想做的是以下内容: 当Blackberry应用程序启动时,会弹出“是/否”对话框。 如果用户选择“是”,请执行一些操作并继续启动。如果用户选择“否”退出应用程序。
我写了一个SSCCE,如果你选择“是”并且你应该听到声音,它应该振动。当然我知道,在调用Alert.vibrate()之后代码会继续,并且它不会等待vibraste完成。无论如何,这只是一个例子。对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()调用周围放了一个synchronized块,因为我读过,调用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
答案 0 :(得分:1)
使用invokeAndWait代替invokeLater。
private void showDialog(final Dialog d)
{
UiApplication.getUiApplication().invokeAndWait(new Runnable()
{
public void run()
{
d.doModal();
this.notify();
}
});
}
答案 1 :(得分:1)
最终解决方案对我有用(并且看起来比我上面所做的更好)如下:
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));
}
}
}
感谢双方的大力支持。