请教:连接远程服务器时,如何显示另外一个等待Form?
连接服务器线程类:
public class LoginThread implements Runnable{
String loginURL= "http://localhost/.../... "
String username= " ";
String password= " ";
public SeClientLoginThread(String username,String password){
this.username=username;
this.password=password;
}
public void run(){
DataInputStream ds=null;
HttpConnection hc=null;
DataOutputStream dos=null;
DataInputStream dis=null;
try{
//我是在这再加一个等待Form的装载代码:
// ConnectServerMidlet connect=new ConnectServerMidlet();
//display.setCurrent(connect.get_form());//显示等待画面
//这样添加后当用户点击LoginMidlet后出现等待画面后程序就死掉了
hc = (HttpConnection)Connector.open(loginURL);
//设置请求属性
hc.setRequestMethod(HttpConnection.POST);
//下面是一堆有关跟服务器取得连接后的验证信息等
//....
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
等待画面:
public class ConnectServerMidlet {
private Image image;
private Form connect;
private ImageItem imageItem;
public Image get_image() {
if (image== null) {
// Insert pre-init code here
try {
image=Image.createImage( "/com/swc/se/SeClient/Logic/waitscreen.png ");
} catch (java.io.IOException exception) {
exception.printStackTrace();
}
// Insert post-init code here
}
return image;
}
public Form get_form() {
if (connect == null) {
// Insert pre-init code here
connect=new Form(null, new Item[] {get_imageItem()});
// Insert post-init code here
}
return connect;
}
public ImageItem get_imageItem() {
if (imageItem== null) {
// Insert pre-init code here
imageItem= new ImageItem( " 连接服务器中,请稍候 ", get_image(), ImageItem.LAYOUT_DEFAULT, null);
// Insert post-init code here
}
return imageItem;
}
}
登录Midlet:
public class LoginMidlet implements CommandListener{
private StringItem stringItem;
private Form login;
private TextField username;
private TextField password;
private Command okCommand;
private Command backCommand;
private List menuForm;
private Display display;
private Thread loginThread;
private Form backForm;
/** Creates a new instance of LoginMidlet */
public LoginMidlet(List menuForm,Display display) {
this.menuForm=menuForm;
this.display=display;
}
public LoginMidlet(Display display) {
this.display=display;
}
/** This method returns instance for login component and should be called instead of accessing login field directly.
* @return Instance for login component
*/
public Form get_login() {
if (login == null) {
// Insert pre-init code here
login = new Form( "用户登录 ", new Item[] {
get_stringItem(),
get_username(),
get_password()
});
login.addCommand(get_backCommand());
login.addCommand(get_okCommand());
login.setCommandListener(this);
// Insert post-init code here
}
return login;
}
/** This method returns instance for stringItem1 component and should be called instead of accessing stringItem1 field directly.
* @return Instance for stringItem1 component
*/
public StringItem get_stringItem() {
if (stringItem == null) {
// Insert pre-init code here
stringItem=new StringItem( " ", "使用本系统前,请您输入正确用户名与密码登录,若没有账号请您返回到主界面注册。 ");
// Insert post-init code here
}
return stringItem;
}
/** This method returns instance for username component and should be called instead of accessing username field directly.
* @return Instance for username component
*/
public TextField get_username() {
if (username == null) {
// Insert pre-init code here
username = new TextField( "用户名: ", " ", 120, TextField.ANY);
username.setInitialInputMode( " ");
// Insert post-init code here
}
return username;
}
/** This method returns instance for password component and should be called instead of accessing password field directly.
* @return Instance for password component
*/
public TextField get_password() {
if (password == null) {
// Insert pre-init code here
password = new TextField( "密码: ", " ", 120, TextField.ANY | TextField.PASSWORD);
// Insert post-init code here
}
return password;
}
/** This method returns instance for okCommand4 component and should be called instead of accessing okCommand4 field directly.
* @return Instance for okCommand4 component
*/
public Command get_okCommand() {
if (okCommand== null) {
// Insert pre-init code here
okCommand = new Command( "\u767B\u5F55 ", Command.OK, 1);
// Insert post-init code here
}
return okCommand;
}
/** This method returns instance for backCommand1 component and should be called instead of accessing backCommand1 field directly.
* @return Instance for backCommand1 component
*/
public Command get_backCommand() {
if (backCommand == null) {
// Insert pre-init code here
backCommand= new Command( "后退 ", Command.BACK, 1);
// Insert post-init code here
}
return backCommand;
}
public void commandAction(Command command, Displayable displayable) {
if(command==backCommand){
//回到目录选择菜单
display.setCurrent(menuForm);
}
else if(command==okCommand){
getLoginInfor();
}
}
public void getLoginInfor(){
//用户点击登录按键后进行身份验证:
String username=get_username().getString();
String password=get_password().getString();
SeClientLoginThread seClientLoginThread=new SeClientLoginThread(username,password);
loginThread=new Thread(seClientLoginThread);
loginThread.start();
}
如何设计这样的问题?
[解决办法]
呵呵,你这个问题也有一个经典的案例,就是iFeedBack
这是我以前摘抄的类代码:
package szx;
import java.util.TimerTask;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Gauge;
/*
* BackgroundTask.java
*
*/
public abstract class BackgroundTask extends TimerTask{
private Thread th;
protected Display display;
private boolean stopped;
//后台任务结束后,显示的屏幕
protected Displayable nextScreen;
//被中断的显示屏幕
protected Displayable prevScreen;
//中断时显示的标题
protected String title;
public BackgroundTask(Display d){
display = d;
th = new Thread(this);
}
public void go(){
stopped = false;
th.start();
}
public void stop(){
stopped = true;
th.setPriority(Thread.MIN_PRIORITY);
}
public void run(){
ProgressGauge pg = null;
pg = new ProgressGauge(this,title,display,prevScreen);
try {
runTask();
} catch (Exception ex) {
//ex.printStackTrace();
}finally{
if(!stopped){
pg.setNextScreen(nextScreen);
pg.stop();
}
}
}
public abstract void runTask()throws Exception;
}
在runTask()写执行网络操作的代码
[解决办法]
呵呵 代码秀啊~ 实在看不下去了 抱歉
[解决办法]
最好在启动网络连接的线程前就切换到等到界面
而不是在网络连接的线程里切换到等待界面