我正在创建一个与服务器上的数据库交互的j2me应用程序。因此,我启动一个线程来连接到服务器。我在一个实现CommandListener
的单独类中处理所有命令操作。
当我尝试获取服务器返回的响应时,我得到一个空字符串。我已经尝试等待连接到服务器的线程返回,但这会使应用程序无响应。
以下是我正在使用的代码。
//my network worker class.
public class NetworkConnector implements Runnable {
//constructor
public NetworkConnector(String url){
//url =>server url to connect to.
Thread thread = new Thread(this);
thread.start();
}
private String serverReply="";
private String url="
//method to connect to the server and return the
//response from the server.
public String sendData(String serverUrl) {
//open streams to connect to the Server.
httpConn = (HttpConnection)
Connector.open(serverUrl,Connector.READ_WRITE, true);
httpConn.setRequestMethod(HttpConnection.GET);
inStream = httpConn.openInputStream();
int read;
while ((read = inStream.read()) != -1) {
sb.append((char) read);
}
return sb.toString();
}
public String getServerReply() {
//serverReply is a class variable.
return serverReply;
}
public void run(){
//call the send method that connects to the server.
serverResponse = sendData(Url);
}
} //end of connector class.
// this class is where all my Command Actions are
//implemented.
public class CommandActionController implements
CommandListener, DataReceiver {
public void commandAction(Command cmd, Displayable d) {
//networkMgr => is the worker class that makes
//connection to the server.
networkMgr = new NetworkConnector("http://localhost
/JsonPhp/login.php?uname=" + loginUserInfo.userName +
"&passwd=" + loginUserInfo.password);
//here am getting the response from the server.
String serverResponse = networkMgr.getServerReply();
//at this point the ServerReponse String is Empty =>
//yet the server is supposed to return some String.
System.out.println("xxxxxxxxxxxxxxxxxx
ServerResponse =" + serverResponse);
}
}//end of CommandListener class.
答案 0 :(得分:3)
您对serverResponse
价值的期望是错误的;当您尝试使用问题中的代码段在commandAction
中获取它时,它可能为空。
为了获得非空值,您需要重新设计方法NetworkConnector.getServerReply()
以使其正确等待,直到线程完成并确实获得服务器响应。
但是,如果你这样做,你还必须重新设计CommandActionController
以保持用户界面的响应 - 用“等待连接到服务器的线程的测试显示只是那个。
重新设计的代码应该只启动服务器连接线程并尽快退出commandAction
(可能会更改为某个“等待屏幕”以让用户看到会发生什么)。只有在获得服务器响应后才能触发下一个屏幕更新。
考虑学习专门针对解释如何正确设计此类应用程序的教程 - Networking, User Experience, and Threads:
本文介绍了MIDlet如何在不影响用户界面的情况下建立网络连接。它包括六个迭代示例,说明多线程网络和等待屏幕的使用......
答案 1 :(得分:0)
以下是我没有java.util.concurrent:
的方法Result handleRequest(){
final String url = // get url
Work work = new Work(url):
Thread t = new Thread(work);
t.start();
// do other stuff
if(t.isAlive()){
// still running
}
// this waits until the work is done
// and it will be safe to access work.result after
// this call has returned.
t.join();
return work.result;
}
然后
class Work implements Runnable{
final String url;
Result result;
public void run(){
this.result = // do your network stuff
}
}
答案 2 :(得分:-2)
你不应该在构造函数中启动一个线程。此外,runnable意味着传递给线程。最简单的(和#34;正确的")方式如下:
Callable
而不是Runnable
。ExecutorService
代替Thread
Future
对象进行异步处理/响应用户这是一个简单的例子。
class Stuff {
final ExecutorService exec =
Executors.newCachedExecutorService(// please see doc);
Result process(String url){
Future<Result> future = exec.submit(new Work(url));
// do some other stuff
if(future.isDone()){
// return result?
}
return future.get(); // this call will wait until result is available
}
}
然后
class Work implements Callable<Result> {
final String url;
Result call() throws Exception {
// do your network stuff here
return result;
}
}
有关详细信息,请参阅java.util.concurrent.ExecutorService.submit()
,java.util.concurrent.Future
和java.util.concurrent.Callable
的文档。