2012-10-13 38 views
2

我想製作一個簡單的應用程序。在用戶看到一個編輯文本的地方..在其中輸入一些文本..然後按發送...然後筆記本電腦上的服務器收到該消息。在Android中使用數據報的簡單網絡連接

現在NetworkOnMainThread異常給我頭痛......該應用完全適用於2.3.3,因爲當時沒有NetworkOnMainThread Exception這樣的事情。

已經搜查了很多..有兩種解決方案

  1. 製作新的線程聯網或
  2. 的AsyncTask。

我試了兩個沒有任何結果。

嘗試1:有獨立的線程:

現在我能明白的是,我不得不啓動一個單獨的線程。好。我做到了。

以下是我的客戶端代碼。

EditText e ; 
TextView tv; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    e= (EditText) findViewById(R.id.editText1); 
    tv = (TextView) findViewById(R.id.textView1); 
    Thread startNetworking = new Thread(new NetworkThread()); 
    startNetworking.start(); 
} 

public void sendMessage(View v){ 
     if(NetworkThread.sendToClient(e.getText().toString())) 
      tv.setText("Status : Successful"); 
     else 
      tv.setText("Status : Unsuccessful"); 
} 

sendMessage是我發送按鈕的onClick函數。我還有一個JAVA文件NetworkThread.java ....

下面是一個代碼:

public class NetworkThread implements Runnable{ 

static DatagramSocket socket; 
static InetAddress add; 
public void run() { 
    try { 
     socket = new DatagramSocket(); 
    } catch (SocketException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    try { 
     add = InetAddress.getByName("192.168.1.12"); 
    } catch (UnknownHostException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 
public static boolean sendToClient(String message){ 
    DatagramPacket p = new DatagramPacket(message.getBytes(),message.getBytes().length,add,4444); 
    try { 
     socket.send(p); 
     return true; 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     return false; 
    } 
} 
} 

這仍然無法正常工作。我首先想要耗盡這個第一次嘗試,然後我將繼續詢問關於AsyncTask和我所嘗試的內容。所以暫時請幫我實現發送和接收字符串這個簡單的任務。

+1

你搜索谷歌在這個話題?這裏有很多類似的問題:https://www.google.com/search?q=NetworkOnMainThread+asynctask 例如:https://gist.github.com/3117827 –

+0

是的,我有。但我的問題與AsyncTask,我已經評論下面的答案。如果解決了,那麼我很高興使用AsyncTask。 – PrateekArora

回答

2

不幸的是,在與NetworkThread相同的類中定義sendToClient()並不意味着它將在您的網絡特定線程上運行。 sendToClient()方法仍將在您的主(UI)線程上運行,因爲它是從onClick()方法中調用的。 UI回調,例如onClick(),總是在UI線程上處理。

我建議使用AsyncTask,因爲它使您能夠在執行任意數據(例如message參數)之前將背景/網絡線程發送到後臺/網絡線程。繼續使用RunnableThread將需要額外的機制來同步UI和網絡線程的執行,並且這些挑戰在幕後由AsyncTask處理。

+2

你可以在這裏找到一個AsyncTask示例:http://stackoverflow.com/questions/9671546/asynctask-android-example –

+0

好的,如果我使用AsyncTask,我不明白的是,我在onClick上給出了這樣的聲明「 myAsync.execute(new String [] {m​​sg})「?現在每次我點擊按鈕,AsyncTask創建新的線程?如果是這樣,以前的線程呢?它會自動關閉它們嗎?另外我會在哪裏初始化我的套接字? – PrateekArora

+1

如果您的應用程序有意義,您可以從'onClick'方法啓動'AsyncTask'。在Android 3之前。0,'AsyncTask'每次都會創建一個新的線程。在3.0+中,它將重用少量線程,並按順序處理它們中的每一個。如果要重新使用套接字,則應在「AsyncTask」之外完成套接字初始化。 (或者,您可以在'AsyncTask'內使用[singleton pattern](http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html)。正確答案取決於你的應用程序要求和個人喜好。) – acj