【问题标题】:Socket thread blocks main thread when receiving套接字线程在接收时阻塞主线程
【发布时间】:2011-07-29 13:29:38
【问题描述】:

我正在使用套接字线程。 发送请求消息后大约需要 5 到 10 秒才能收到消息。 在那段时间里,我希望我的主线程显示“请稍候”弹出窗口。 程序的流程大概是这样的。

  1. 显示弹出窗口
  2. 创建套接字线程。 -> 这将连接到服务器
  3. 向服务器发送请求消息
  4. 接收消息。

我的问题是显示弹出窗口没有出现, 直到套接字线程收到它的消息。

谁能告诉我解决这个问题的方法?

公共类 LoginActivity 扩展 Activity {

.... <some coded>

public void onClickLogin(View view) {
    Log.d(this.toString(), "onClickLogin");

    showLoginLoadingPopup();

    String login_id = ((EditText)findViewById(R.id.login_id)).getText().toString();
    String login_pwd = ((EditText)findViewById(R.id.login_pwd)).getText().toString();

    conn = new Connection(handler, 1, null);
    conn.start();
    conn.sendData(Connection.SSPH_USERCERT, new String[] {login_id, login_pwd});
}

}

公共类 Connection 扩展 Thread 实现 ConnectionConstant {

private InetAddress serverAddr;
private int serverPort;
private Socket socket;
PrintWriter out;
BufferedReader in;
private Handler handler;

public Connection(Handler h, int type, ServerClass server) {
    Log.d(this.toString(), "Conncetion");
    setServerInfo(type, server);
    handler = h;

    try {
        connect();
    } catch (Exception e) {
        Log.e(this.toString(), "Error", e);
    }
}

public void run() {
    Log.d(this.toString(), "run");
    try {
        queue();
        disconnect();
    } catch (Exception e) {
        Log.i(this.toString(), "Information", e);
    }
}

private void connect() throws Exception {
    if (serverAddr != null)
        Log.d(this.toString(), "connect " + serverAddr.getHostName() + "("
                + Integer.toString(serverPort) + ")");
    else
        Log.d(this.toString(), "connect ");
    socket = new Socket(serverAddr, serverPort);
    socket.setSoLinger(true, 3000);
    // UTF-8
    out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
            socket.getOutputStream())), true);
    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    Log.i(this.toString(), "Socket connected!");
}

private void queue() throws Exception {
    Log.d(this.toString(), "queue");
    while (true) {
        String sRcv = null;
        sRcv = receive();

        if (sRcv.length() > 0)
            parseData(sRcv);

        Thread.sleep(500);
        Thread.yield();
    }
}

private void send(String str) throws IOException {
    Log.d(this.toString(), "send");
    if (!socket.isConnected())
        return;
    Log.i(this.toString(), "Send : " + str);
    out.println(str);
}

private String receive() throws Exception {
    Log.d(this.toString(), "receive");
    if (!socket.isConnected())
        return null;

    StringBuilder sb = new StringBuilder();
    String str = "";

    while ((str = in.readLine()) != null) {
        Log.i(this.toString(), "Receive : " + str);
        sb.append(str + "\n");
    }
    return sb.toString();
}

}

【问题讨论】:

  • 顺便说一下,我在程序中使用 JAVA,在 UI 中使用 ANDROID
  • 你可能做错了什么,比如在线程中调用 run 而不是 start。显示您的代码。
  • 不看代码很难说有用的东西。特别是对于诸如线程错误之类的事情。

标签: java android multithreading sockets


【解决方案1】:

使用异步任务:

    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
        @Override
        protected void onPreExecute() {
            // show dialog
        }

        @Override
        protected Void doInBackground(Void... params) {
            // connect to the server
        }

        @Override
        protected void onPostExecute(Void result) {
            // close dialog
        }
    };

    task.execute();

onPreExecute()onPostExecute()onProgressUpdate() 在 UI 线程上调用。

doInBackground() 在后台线程上调用。

更多关于 AsyncTask:http://developer.android.com/reference/android/os/AsyncTask.html

【讨论】:

    【解决方案2】:
     dialog = ProgressDialog.show(this, "", "Loading",true);
     Runnable myRun = new Runnable(){
          public void run(){
               //DO ALL NETWORKING
               //FINALLY DO THIS
               runOnUiThread(new Runnable() {
                    public void run() {
    
                    }
               });     
          };
     Thread T = new Thread(myRun);
     T.start();
    

    【讨论】:

    • 我无法使用它,因为我的网络类与我的 UI 类是分开的,但感谢您提供的信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-23
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 2018-02-16
    相关资源
    最近更新 更多