多线程技术是JAVA ME中的关键技术,应用十分频繁,尤其是在游戏中。但是对于新手来说,又容易忽略或错误的使用多线程,导致程序堵塞,而无法响应用户的输入请求。
由于笔者对于游戏开发不是十分了解,所以本文将仅就多线程技术在JAVA ME应用程序中的使用展开讨论。本文主要包含如下部分:
多线程与联网
手机中,所有的MIDlet程序都是由Application Manager Software(AMS)管理的。当MIDlet初始化后,AMS就会调用MIDlet的startApp()方法,此时MIDlet就进入了Acitive状态。在JAVA ME中有些操作可能会导致程序堵塞,比如连接网络等。如果这些操作与主程序在同一个主线程中完成,那么由于堵塞会造成程序长时间无法返回,也就无法响应用户的其他操作了。所以,如果我们在commandAction()中进行了联网的操作,则会造成如上所述的情况。
下面,将通过一个例子来演示如上的情况,并使用多线程最终解决此问题。这是一个“Echo Message”实例,手机端向服务器端发送一条消息,服务器得到此消息后直接返回给手机端。
首先,创建一个NetworkConnection类来封装联网相关的操作,这样,MIDlet中只需调用此类中的方法就可以完成联网的操作。代码如下:
以下是引用片段:
/* * NetworkConnection.java * * Created on 2006年7月20日, 下午2:54 * */ package nju.hysteria.thread.connection; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import javax.microedition.io.Connector; import javax.microedition.io.HttpConnection; /** * * @author Magic */ public class NetworkConnection { private static final String URL = "http://localhost:8080/thread/"; private HttpConnection httpConnection; private String message; public NetworkConnection(String message) { this.message = message; connect(); } /** * Connect to web server. * */ public void connect(){ try { httpConnection = (HttpConnection) Connector.open(URL); httpConnection.setRequestMethod(HttpConnection.POST); } catch (IOException ex) { System.out.println("Can not open connection!"); ex.printStackTrace(); } } /** * Send message to server. * @throws java.io.IOException */ public void sendMessage() throws IOException{ DataOutputStream out = httpConnection.openDataOutputStream(); out.writeUTF(message); out.close(); } /** * Receive message from server. * @throws java.io.IOException * @return */ public String receiveMessage() throws IOException { DataInputStream in = httpConnection.openDataInputStream(); String message = in.readUTF(); in.close(); return message; } /** * Close connection. */ public void close(){ if(httpConnection!=null){ try { httpConnection.close(); } catch (IOException ex) { ex.printStackTrace(); } } } } |
以下是引用片段: /* * MalConnectionMidlet.java * * Created on 2006年7月20日, 下午2:53 */ package nju.hysteria.thread.connection; import java.io.IOException; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; /** * * @author Magic * @version */ public class MalConnectionMidlet extends MIDlet implements CommandListener { private Display display; private TextBox text; private Command showCommand; public MalConnectionMidlet(){ display = Display.getDisplay(this); text = new TextBox("Message","请使用‘问候’命令发送消息",100,TextField.ANY); showCommand = new Command("问候",Command.SCREEN,1); text.addCommand(showCommand); text.setCommandListener(this); } public void startApp() { display.setCurrent(text); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command command, Displayable displayable) { if(command==showCommand){ /** * 在当前的线程中直接进行联网操作,造成程序堵塞。 */ String message = null; NetworkConnection connection = new NetworkConnection("Hello World"); try { connection.sendMessage(); message = connection.receiveMessage(); connection.close(); } catch (IOException ex) { ex.printStackTrace(); } text.setString(message); } } } |
图1
以下是引用片段: Warning: To avoid potential deadlock, operations that may block, such as networking, should be performed in a different thread than the commandAction() handler. |
这就是因为没有使用多线程造成的。下面,就来看看如何使用多线程来解决此问题。