WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章J2ME技术进阶教程解决手机开发中难点:如何实现J2ME对话框

解决手机开发中难点:如何实现J2ME对话框
作者:不详  来源:.j2medev.com  发布时间:2005-7-29 9:05:50

在手机这么小的屏幕上开发应用,难点之一就是频繁的屏幕切换。尽管midp2.0的UI部分已经很丰富了,但这些UI部件都是基于事件回调的。这在处理大量的、简单的问答式交互时显得力不从心。

本文实现了一个阻塞当前线程的对话框,简要地说,你可以使用诸如win32API中dialog函数那样的方式来实现对话框并阻塞等待返回值,然后根据返回值进行不同的处理。听起来很诱人吧。

首先回顾一下MIDP UI的事件处理机制。有两个要点:

1)首先UI部分由系统的一个线程负责维护。也就是说不能阻塞系统的事件处理方法。

2)事件处理使用的是一种回调机制。首先UI部件使用诸如setCommandListener之类的方法为自己注册一个回调接口(其中的回调方法由用户实现);等到触发了相应事件就调用这个注册好的接口的回调方法。

以下是一个实现了CommandListener的类的代码片断:


Form f=new Form("Hello world");
f.addCommand(exit);
f.setCommandListener(this);




可以想象基于事件回调的处理方式,在处理大量的、简单的问答式交互时显得力不从心。你不得不为每一个仅仅是询问要不要继续的对话框而实现一个又一个类,或者处理一个复杂的回调函数。如果选择后者,那么在一个又一个的if-else中处理不同逻辑事件的代码片断一定会烦死你。

较好的做法

这时候我们不免怀念一下win32 Api中对话框函数的处理方式:


int choose=Dialog(title,type……);
if(choose==OK){……}
else if(choose==Cancel){……}




这样处理将会阻塞当前线程,等待返回值,然后根据返回值进行处理。这样做的原因就是在一个逻辑性很完整的任务中,你可以一次性在一个回调方法中完成所有逻辑,而不必为了问询简单的YES/NO问题而在不同的类中间跳来跳去。

如何在MIDP下实现

我们遇到的第一个问题来自于我们的方法必须要阻塞当前线程等待返回值。也就是说,这个对话框不能在UI的回调中直接运行,比如commandAction中。解决办法是将所有的事件处理都放到一个线程类中处理。(这是一点额外的负担,但不可避免)。还好这个工作量不大,要想实现两个对象之间的通信也不难。

第二个问题是如何阻塞当前的线程,我们祭出java线程的三板斧之wait()/notifyAll()。我们可以指定一个信号量(初值false),当其为false时阻塞当前线程,在得到用户通知后将信号量改为true,并唤醒线程。

下面看一下主要思路:


看一下代码:

Dialog.java
/*
*为j2me提供阻塞的dialog调用方法。
*但前提是,
如果要在UI的相应线程中运行
(比如commonAction),
*则需首先打开一个新的线程中使用,
因为UI线程是不可以阻塞的。
*这个版本虽然包含在coreUI2.0中,
但midp1.0也可以用。seimens s57通过测试。
*
*/
package bean;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;

/**
* @author Favo
*/
public class Dialog
{
//主类
private boolean blockFlag = false;
public static int YES=0;
public static int NO=1;
private int returnValue;
private Display display;

public Dialog(Display display){
this.display=display;
}

public void setReturnValue(int i)
{
//设置返回值
returnValue=i;
}

synchronized boolean getBlockFlag()
{
//取得信号量
return blockFlag;
}

synchronized void setBlockFlag(boolean flag)
{
//设置信号量
blockFlag = flag;
}

public int show(String title,
String content,
String yes,String no)
{
setBlockFlag(false);
Form f=new DialogForm
(this,title,content,yes,no);
display.setCurrent(f);
//显示UI
try {
while(getBlockFlag()==false)
{
//如果用户没选择阻塞
synchronized (this)
{
wait();
}
}
} catch (InterruptedException e)
{
e.printStackTrace();
System.out.println
("InterruptedException in Dialog.show");
}
return returnValue;
//返回
}


public void wakeup()
{
synchronized (this)
{
//唤醒阻塞的线程
notifyAll();
}

}
}

class DialogForm extends
Form implements CommandListener
{
//UI部分
Command yesCMD;
Command noCMD;
Dialog dialog;

public DialogForm
(Dialog dialog,String title,
String content,String yes,String no)
{
super(title);
this.dialog=dialog;
append(content);
yesCMD=new Command(yes,Command.OK,1);
noCMD=new Command(no,Command.CANCEL,1);
addCommand(yesCMD);
addCommand(noCMD);
setCommandListener(this);
}

public void commandAction
(Command c, Displayable d)
{
if(c==yesCMD)
{
dialog.setBlockFlag(true);
dialog.setReturnValue(Dialog.YES);
dialog.wakeup();
}else if(c==noCMD)
{
dialog.setBlockFlag(true);
dialog.setReturnValue(Dialog.NO);
dialog.wakeup();
}
}

}




我编写了一个Test。当用户按下show按钮时,开启对话框,并将用户的选择打印出来。


DialogTest.java
package bean;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;
import javax.microedition.
midlet.MIDletStateChangeException;


public class DialogTest extends
MIDlet implements CommandListener
{
Display display;

Form f = new Form("DialogTest");

Command showCMD =
new Command("show", Command.ITEM, 1);

public DialogTest

[1] [2]  下一页

[] [返回上一页] [打 印]
文章评论

用户名: 查看更多评论

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

         (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码