標籤:des android style class blog code
最近要做一個Android的項目,用到socket和伺服器之間互動,研究了一個小demo。主要遇到了以下幾個問題:
1.用戶端建立socket對象時一直失敗NetworkOnMainThreadException,查了一下,原因是4.0之後在主線程中執行http請求會報這個錯。解決辦法是將代碼放到了一個新線程中,問題就解決了。
2.伺服器接收到用戶端資訊後反饋給用戶端資訊,將該資訊表示在用戶端UI上時報“android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.”異常。該問題原因是,在主線線程之外的線程中直接更新頁面顯示常會報錯。解決辦法是通過runOnUiThread方法將線程對象傳過去,這樣在主線程中就能執行該線程的內容了,當然還有其他辦法。可參考連結http://blog.csdn.net/shenyuemei/article/details/11030679。
下面是程式碼:
布局檔案
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/et_hint" /> <Button android:id="@+id/send" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/txt_send" /> <TextView android:id="@+id/tv" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>
服務端代碼
package testDemo;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class Server implements Runnable { public static void main(String[] args) { Thread desktopServerThread = new Thread(new Server()); desktopServerThread.start(); } @Override public void run() { try { ServerSocket serverSocket = new ServerSocket(8888); while (true) { // 阻塞,等待接收客戶請求。 Socket client = serverSocket.accept(); System.out.println("接受到用戶端的請求。"); try { BufferedReader in = new BufferedReader( new InputStreamReader(client.getInputStream())); // 讀取用戶端發過來的資訊 String read = in.readLine(); System.out.println("用戶端發送訊息為 : " + read); // 向用戶端返回資訊 PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(client.getOutputStream()))); if (read != null) { out.println("你發送給伺服器的資訊為 : " + read); out.flush(); } out.close(); in.close(); } catch (Exception e) { e.printStackTrace(); } finally { client.close(); } } } catch (Exception e) { e.printStackTrace(); } }}
用戶端代碼
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.InetAddress;import java.net.Socket;import java.net.UnknownHostException;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;public class ClientActivity extends Activity { private Button send = null; private EditText content = null; private TextView tv = null; String msg = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.socket2); send = (Button)findViewById(R.id.send); content = (EditText)findViewById(R.id.content); tv = (TextView)findViewById(R.id.tv); send.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { setTitle("socket"); new Thread(thread1).start(); } }); } /*Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { myHandler.post(thread1); } };*/ /** * 該線程主要是向伺服器發送訊息和接收訊息 */ Runnable thread1 = new Runnable() { @Override public void run() { Socket socket = null; try { InetAddress serverAddr = InetAddress.getByName("192.168.1.110"); socket = new Socket(serverAddr, 8888); //想伺服器發送訊息 PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))); out.println(content.getText().toString()); out.flush(); //讀取伺服器返回的訊息 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); msg = in.readLine(); //把該子線程當做參數傳遞,這樣在主UI線程就可更新UI ClientActivity.this.runOnUiThread(updateThread); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }; Runnable updateThread = new Runnable() { @Override public void run() { if (msg != null) { tv.setText(msg); } else { tv.setText("data error."); } } };}