Android线程bug

时间:2014-06-01 11:11:36

标签: java android multithreading android-asynctask

我实际上正在开发一个聊天安卓应用程序。

我对我创建的主题有疑问。基本上,我的客户端应用程序有一个连接到服务的活动。该服务负责客户端和服务器之间的通信。 (我也使用Asynctask)

我有两个主要方案:

  • 我向服务器发送请求(刷新好友列表,添加好友,登录...),预计服务器的响应是没有问题的。

  • 第二种情况是关于来自服务器的意外请求(当另一个人想要与您通信时)。为此,我在我的服务类中创建了一个这样的线程。

    public void launchListener(){

            Runnable SocketListener = new Runnable(){
    
                public void run(){              
                    String msg = "";
                    String[] msg_parts = {"","",""};                
                    while(true){
                        try {
                            if (in.available() > 0){                            
                                msg = in.readLine();
                                msg_parts = msg.split(" ");                         
                                if (msg_parts[0].equals("CONNECTION")){
                                    Log.d("SocketService", "Broadcasting message");
                                    Intent intent = new Intent("ask.connection");
                                    intent.putExtra("nickname", msg_parts[1]);
                                    sendBroadcast(intent);
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
              };
              Thread t = new Thread(SocketListener);
              t.start();
        }
    

问题是,该线程只等待“连接”,所以它也拦截了服务器的预期响应,我不知道为什么但这个线程冻结了我的应用程序。 这只是一种可能性,但也许是因为我也在其他地方使用 readLine ,它不起作用。

这里我使用readLine作为Asyntask中的预期响应:

protected String doInBackground(String... message) {
       this.message = message[0];
       this.out =  service.getOut();
       this.in = service.getIn();
       try {
          this.out.writeBytes(this.message + "\n");
          this.out.flush();
       } catch (IOException e) {

           e.printStackTrace();
       }

       response = readLine(this.in);

       return response;
   }

我真的不知道为什么它不起作用,也许asynctask readLine首先读取响应,然后当我的线程读取它时,DataInputStream为空并且冻结。

无论如何,谢谢你的帮助!!

1 个答案:

答案 0 :(得分:1)

如果(in.available() > 0){评估为false,则表示您正在浪费整个CPU核心,如果您在单核设备上运行,您的设备将会冻结。

使用Thread.sleep缓解此问题并进入BlockingQueue http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

此外,您正在从两个线程访问您的服务,我希望它是线程安全的。

while(true){
  try {
    if (in.available() > 0) {                            
      msg = in.readLine();
      msg_parts = msg.split(" ");                         
      if (msg_parts[0].equals("CONNECTION")){
        Log.d("SocketService", "Broadcasting message");
        Intent intent = new Intent("ask.connection");
        intent.putExtra("nickname", msg_parts[1]);
        sendBroadcast(intent);
      }
    } else {
      Thread.sleep(100); // Or any sufficient delay.
    }
  } catch (IOException e) {
    e.printStackTrace();
  } catch (InterruptedException ie) {
    Thread.currentThread().interrupt();
    break;
  }
}