J2ME线程编程

时间:2012-10-22 06:55:14

标签: multithreading java-me midp lcdui

我正在创建一个与服务器上的数据库交互的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.

3 个答案:

答案 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;正确的")方式如下:

  1. 实施Callable而不是Runnable
  2. 使用ExecutorService代替Thread
  3. 使用Future对象进行异步处理/响应用户
  4. 这是一个简单的例子。

    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.Futurejava.util.concurrent.Callable的文档。