2012-10-12 54 views
3

我是新來的android應用程序開發。我試圖開發一個Android服務器客戶端聊天如何創建asyncTask來防止networkOnMainThreadException

爲我的第一個項目。這是客戶端的代碼。當客戶端按btnJoin,

它將連接到服務器併發送一個字符串。我讀過很多例子,其中很多都是

看起來像這樣。我得到了networkOnMainThreadException。我如何使asyncTask阻止

這個問題?任何幫助將非常感激。

btnJoin = (Button) findViewById(R.id.buttonJoin); 
btnJoin.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     Socket socket = null; 
     DataOutputStream dataOutputStream = null; 
     DataInputStream dataInputStream = null; 
     try { 
      socket = new Socket("192.168.1.4", 9092); 
      dataOutputStream = new DataOutputStream(socket.getOutputStream()); 
      dataInputStream = new DataInputStream(socket.getInputStream()); 
      dataOutputStream.writeUTF("Hello server!"); 
      txtIP.append(dataInputStream.readUTF() + "\n"); 
     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (socket != null) { 
       try { 
        socket.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      if (dataOutputStream != null) { 
       try { 
        dataOutputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      if (dataInputStream != null) { 
       try { 
        dataInputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
}); 
+0

@avd感謝編輯工作,我的問題。我會適當地格式化我的下一個問題。 :D –

回答

2

更改您的代碼爲:

btnJoin.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View view){ 

       new LongOperation().execute(""); 

    } 
} 

private class LongOperation extends AsyncTask<String, Void, String> { 
    Socket socket = null; 
    String strresult=""; 
     DataOutputStream dataOutputStream = null; 
     DataInputStream dataInputStream = null; 
      @Override 
      protected String doInBackground(String... params) { 

     try { 
      socket = new Socket("192.168.1.4", 9092); 
      dataOutputStream = new DataOutputStream(socket.getOutputStream()); 
      dataInputStream = new DataInputStream(socket.getInputStream()); 
      dataOutputStream.writeUTF("Hello server!"); 
      strresult.append(dataInputStream.readUTF() + "\n"); 
     // txtIP.append(dataInputStream.readUTF() + "\n"); 
     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (socket != null) { 
       try { 
        socket.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      if (dataOutputStream != null) { 
       try { 
        dataOutputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      if (dataInputStream != null) { 
       try { 
        dataInputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

       return strresult; 
      }  

      @Override 
      protected void onPostExecute(String result) { 
       TextView txtIP= (TextView) findViewById(R.id.txtIP); 
       // txtIP.append(result + "\n"); 
       txtIP.setText(result + "\n"); 

      } 

      @Override 
      protected void onPreExecute() { 
      } 

    } 
+0

謝謝你的回覆。我遵循你的代碼,它似乎工作。我在void onPostExecute上添加了一行。 Log.d( 「OnPostExecute」, 「完成」)。但日誌從不出現。任何線索? –

+0

嘗試System.out.println(「OnPostExecute,Done」);在TextView之前txtIP =(TextView)findViewById(R.id.txtIP);和txtIP.setText(result +「\ n」);在兩個地方 –

+0

第一個println觸發,第二個println不觸發。沒關係,數據總是成功發送。感謝您的建議。非常感謝您的幫助。 –

1

使用的AsyncTask是這樣的:

首先有它嵌套在你的類,它應該類似於:

private class Communicator extends AsyncTask<Void, Void, Boolean> { 
    String tmp; 
    String err; 

    @Override 
    protected Boolean doInBackground() { 

     try { 
       socket = new Socket("192.168.1.4", 9092); 
       dataOutputStream = new DataOutputStream(socket.getOutputStream()); 
       dataInputStream = new DataInputStream(socket.getInputStream()); 
       dataOutputStream.writeUTF("Hello server!"); 


     } catch (UnknownHostException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } finally { 
       if (socket != null) { 
        try { 
         socket.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
       if (dataOutputStream != null) { 
        try { 
         dataOutputStream.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
       if (dataInputStream != null) { 
        try { 
         dataInputStream.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 

     return true; 
    } 

    @Override 
    protected void onPreExecute() { 

    } 

    @Override 
    protected void onPostExecute(Boolean result) { 
     txtIP.append(dataInputStream.readUTF() + "\n");    


    } 
} 

當你有AsyncTask,你可以像這樣啓動它:

... 
@Override 
public void onClick(View v) { 
Communicator c=new Communicator(); 
c.execute(); 
} 
.... 
+0

txtIP.append(dataInputStream.readUTF()+「\ n」);無法在doInBackground()內工作 –

+0

txtIP.append(dataInputStream.readUTF()+「\ n」);無法從doInBackground() –

+0

訪問謝謝您的回覆。但是您的解決方案似乎存在問題。真的很感激它。 –

0

嘗試執行這段代碼在你的應用程序

private class LongOperation extends AsyncTask<Object, Integer, Object> { 

     @Override 
     protected void onPreExecute() { 



      super.onPreExecute(); 
     } 

     @Override 
     protected Object doInBackground(Object... params) { 
      //do hard work here 
           return params; 
     } 

     @Override 
     protected void onProgressUpdate(Integer... values) { 


     } 

     @Override 
     protected void onPostExecute(Object result) { 



      super.onPostExecute(result); 
     } 
    } 
0

的AsyncTask必須被繼承使用。子類將覆蓋的至少一種方法(doInBackground(參數...)),和最經常將覆蓋的第二個(onPostExecute(結果)。)

這裏是子類的一個例子

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { 
    protected Long doInBackground(URL... urls) { 
     int count = urls.length; 
     long totalSize = 0; 
     for (int i = 0; i < count; i++) { 
      totalSize += Downloader.downloadFile(urls[i]); 
      publishProgress((int) ((i/(float) count) * 100)); 
      // Escape early if cancel() is called 
      if (isCancelled()) break; 
     } 
     return totalSize; 
    } 

    protected void onProgressUpdate(Integer... progress) { 
     setProgressPercent(progress[0]); 
    } 

    protected void onPostExecute(Long result) { 
     showDialog("Downloaded " + result + " bytes"); 
    } 
} 

一旦創建了任務執行得很乾脆:

new DownloadFilesTask().execute(url1, url2, url3); 

瞭解更多詳情請參考以下鏈接...

http://www.vogella.com/articles/AndroidPerformance/article.html

http://developer.android.com/reference/android/os/AsyncTask.html