2014-04-27 63 views
0
public class SocketThread { 

private boolean connect = false; 
private String ip = "*********"; 
private int port = ****; 
private Socket socket; 
private SocketAsync socketAsync; 

public SocketThread() { 
    socketAsync = new SocketAsync(); 
    socketAsync.execute(); 
} 

public void setMessenger(SocketServiceMessenger messenger) { 
    this.socketServiceMessenger = messenger; 
} 

public void setConnectFlag(boolean connect) { 
    this.connect = connect; 
} 

public void sentData(JSONObject json) { 
    socketAsync.sentData2(json); 
} 

private class SocketAsync extends AsyncTask<Void, Void, String> { 

    private PrintWriter printWriter; 

    @Override 
    protected String doInBackground(Void... params) { 
     String msgStr; 
     String type; 
     try { 
      socket = new Socket(InetAddress.getByName(ip),port); 
      OutputStreamWriter streamOut = new OutputStreamWriter(socket.getOutputStream(), "UTF-8"); 
      printWriter = new PrintWriter(streamOut); 
      streamOut.flush(); 
      BufferedReader streamIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); 
      while(socket.isConnected()) { 
       msgStr = streamIn.readLine(); 
       System.out.println(msgStr); 
       if(!connect) { 
        socket.close(); 
       } 
      } 
      System.out.println("SocketDisconnected"); 
     } catch (Exception e) { 
      System.out.println(e.toString()); 
     } 
     return null; 
    } 

    public void sentData2(JSONObject json) { 
     if(socket.isConnected()) { 
      printWriter.println(json.toString()); 
      printWriter.flush(); 
      System.out.println("OUT : " + json); 
     } 
    } 

} 

我得到android.os.NetworkOnMainThreadException調用sentData()NetworkOnMainThreadException中的AsyncTask【解析】

現在我用

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
    StrictMode.setThreadPolicy(policy); 

來解決問題,但我想知道如何當以真實的方式使用asynctask。

此代碼適用於實時接收服務器消息的在線遊戲,也可以通過調用sentData()從某個活動向服務器發送消息。


解決

Example: Android bi-directional network socket using AsyncTask

+0

請發佈堆棧跟蹤。 – CommonsWare

+0

它只是說「android.os.NetworkOnMainThreadException」 – Tanggyxyz

+0

請發佈**整個堆棧跟蹤**。你所顯示的只是例外描述。您需要查看代碼的哪些行觸發了此完全堆棧跟蹤中包含的異常。 – CommonsWare

回答

0

您應該設置類是公共的,沒有外部類需要。

public class SocketAsync extends AsyncTask<String, String, String> { 

     private PrintWriter printWriter; 

     @Override 
     protected String doInBackground(String... params) { 
      //You do things here. 
     } 
    } 

這是你如何設置類,並在活動類,你只需像代碼調用此:

new SocketAsync(this).execute(/*Put parameters here.*/); 

希望這會有所幫助。

0

方法SocketAsync.sentData2()調用socket.isConnected()。這是在主線程上調用的,因爲在主線程上調用SocketThread.sendData2()

代碼在其被調用的線程上執行。僅僅因爲你把代碼放在你的AsyncTask類中並不意味着它會在後臺線程上。只有doInBackground()中的代碼被保證在後臺執行,因爲Android框架需要注意從後臺線程調用該方法。如果你自己調用它,它會在任何稱爲它的線程上執行。 sentData2()也不例外。

+0

另外,正如nKn提到的,不要做setThreadPolicy的事情。 – Karakuri

0

您正在使用Asynctask錯誤。當你調用execute方法時,doInBackground被調用,它在不同的線程上運行。您使用AsyncTask中的onPostExecute方法將數據返回到主線程(一種回調方法)。此方法在主UI線程上運行。

sendData方法需要一個新的AsyncTask,帶有一個新的doInbackground和一個新的調用來執行。

相關問題