套接字线程在接收时阻塞主线程

时间:2011-07-29 13:29:39

标签: java android multithreading sockets

我正在使用套接字线程。 发送请求消息后,接收消息大约需要5到10秒。 在那段时间我希望我的主线程显示“请等待”弹出窗口。 程序的流程看起来像这样。

  1. show Popup
  2. 创建套接字线程。 - >这将连接到服务器
  3. 向服务器发送请求消息
  4. 收到消息。
  5. 我的问题是节目弹出窗口没有出现, 直到套接字线程收到消息后。

    有人可以告诉我这个问题的解决方法吗?

    公共类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});
    }
    

    }

    public class Connection extends 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();
    }
    

    }

2 个答案:

答案 0 :(得分:3)

使用AsyncTask:

    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();
在UI线程上调用

onPreExecute()onPostExecute()onProgressUpdate()

在后台线程上调用

doInBackground()

有关AsyncTask的更多信息:http://developer.android.com/reference/android/os/AsyncTask.html

答案 1 :(得分:0)

 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();