Android通訊端編程

來源:互聯網
上載者:User

第一步,使用本機和本機上Android模擬器通訊,出現無法通訊現象。原因是android的主ui線程不能執行一個背景工作執行緒,也就是執行網路操作之類的.
兩種方法可以解決:
1\參考http://android.yyable.com/reference/android/os/StrictMode.html

2\刪除androidmanifest.xml裡的<uses-sdk android:minSdkVersion="14" />

也可以用其他方式處理,如handler。

開始以為是許可權的問題。

android模擬器作為伺服器端接收來自PC的UDP資料包,
需要在模擬器上做連接埠映射,用的命令跟TCP的時候有些不同
redir add udp:8000:9000
這樣做了之後就可以收到UDP的包了!

建立線程有兩種方法:繼承Thread類和實現Runnable介面。方法一:繼承 Thread 類,覆蓋方法 run(),我們在建立的 Thread 類的子類中重寫 run() ,加入線程所要執行的代碼即可。下面是一個例子:
public class MyThread extends Thread {int count= 1, number;public MyThread(int num) {number = num;System.out.println("建立線程 " + number);}public void run() {while(true) {System.out.println("線程 " + number + ":計數 " + count);if(++count== 6) return;}}public static void main(String args[]) {for(int i = 0; i < 5; i++) new MyThread(i+1).start();}}

方法二:實現 Runnable 介面 Runnable 介面只有一個方法 run(),我們聲明自己的類實現 Runnable 介面並提供這一方法,將我們的線程代碼寫入其中,就完成了這一部分的任務。但是 Runnable 介面並沒有任何對線程的支援,我們還必須建立 Thread 類的執行個體,這一點通過 Thread 類的建構函式public Thread(Runnable target);來實現。下面是一個例子:

public class MyThread implements Runnable {int count= 1, number;public MyThread(int num) {number = num;System.out.println("建立線程 " + number);}public void run() {while(true) {System.out.println("線程 " + number + ":計數 " + count);if(++count== 6) return;} }public static void main(String args[]) {for(int i = 0; i < 5; i++) new Thread(new MyThread(i+1)).start();}}

Runnable說白了只是個回調介面,並不是所有的Runnable都是用於線程的;如果把它做為線程:傳給Thread類傳給Executor類

只要是關於UI相關的東西,就不能放在子線程中,因為子線程是不能操作UI的,只能進行資料、系統等其他非UI的操作。

1.要把Handle對象傳遞的東西放在一個訊息迴圈的隊列當中,如果沒有這個訊息迴圈隊列的話,就會報錯!

2.在做比較簡單線程通訊的時候,我們只是在主Activity線程中使用Handler.sendMessage(Message)方法來實現訊息的發送,用Handler.handleMessage(Message)類實現訊息的擷取,這似乎沒有什麼錯誤,而且如果在我們自己開啟的普通線程中向主Activity線程發送訊息似乎也不會有什麼錯誤,可以捕獲我們想要的訊息。

3.但是如果我們接收訊息的線程不在主線程那麼而是一個普通線程,那麼就會報錯。為什麼會這樣呢?原因就是因為在我們自訂的普通線程中沒有訊息迴圈隊列。那麼怎麼來實現一個訊息迴圈隊列呢?(假設我們都複寫了handleMessage(Message)方法)

(1)這是最簡單的方法,是在執行個體化Handler對象的時候傳入調用HandlerThread.getLooper()獲得的Looper對象,這個Looper就是我們需要的訊息迴圈隊列。當然這個HandlerThread對象必須調用start()方法去讓他開啟的線程運行。

(2)這個方法是模仿HandlerThread類的run()方法寫出來的。就是在定義Handler對象的前加上Looper.prepare()方法,讓訊息迴圈開始準備,在定義完以後在調用Looper.loop();然訊息迴圈開始運行。其實這兩個方法本質上是沒有沒有區別的,都是給一個普通線程添加了一個訊息佇列。

4.那麼為什麼在Activity中就沒有什麼問題呢?

原因是Activity其實什麼也不是,只是一個大怪物,他把很多功能都整合到了一起,並且把他封裝起來,當然也包括一個訊息迴圈隊列(這個訊息迴圈隊列由系統來維護),所以在簡單的主Activity中用Handler傳遞訊息不會報錯。有人說Activity是介面其實並不是這樣的,我們看到的只不過是一個Window或者View,他用Window的功能監聽事件,用View的功能顯示介面,還有整合了資料存放區等功能,等等。

通訊代碼:

 UDP通訊實現:UDP使用DatagramSocket對象來實現 UDP的用戶端代碼實現如下:       public static void main(String[] args) {       try {           //首先建立一個DatagramSocket對象           DatagramSocket socket = new DatagramSocket(4567);           //建立一個InetAddreeInetAddress serverAddress = InetAddress.getByName("192.168.1.104");           String str = "hello";  //這是要傳輸的資料           byte data [] = str.getBytes();  //把傳輸內容分解成位元組           //建立一個DatagramPacket對象,並指定要講這個資料包發送到網路當中的哪個、地址,以及連接埠號碼           DatagramPacket packet = new DatagramPacket(data,data.length,serverAddress,4567);           //調用socket對象的send方法,發送資料           socket.send(packet);       } catch (Exception e) {           // TODO Auto-generated catch block           e.printStackTrace();       }}  UDP的服務端代碼實現如下://建立一個DatagramSocket對象,並指定監聽的連接埠號碼              DatagramSocket socket = new DatagramSocket(4567);              byte data [] = new byte[1024];              //建立一個空的DatagramPacket對象               DatagramPacket packet = new DatagramPacket(data,data.length);              //使用receive方法接收用戶端所發送的資料,              //如果用戶端沒有發送資料,該進程就停滯在這裡              socket.receive(packet);              String result = new String(packet.getData(),packet.getOffset(),packet.getLength());        System.out.println("result--->" + result); 5、  TCP通訊的實現:TCP使用Socket對象 TCP協議用戶端實現://建立一個Socket對象,指定伺服器端的IP地址和連接埠號碼           Socket socket = new Socket("192.168.1.104",4567);           //使用InputStream讀取硬碟上的檔案           InputStream inputStream = new FileInputStream("f://file/words.txt");           //從Socket當中得到OutputStream           OutputStream outputStream = socket.getOutputStream();           byte buffer [] = new byte[4*1024];           int temp = 0 ;           //將InputStream當中的資料取出,並寫入到OutputStream當中           while((temp = inputStream.read(buffer)) != -1){              outputStream.write(buffer, 0, temp);           }           outputStream.flush();       }    TCP協議伺服器端現實:       //聲明一個ServerSocket對象        ServerSocket serverSocket = null;        try {                //建立一個ServerSocket對象,並讓這個Socket在4567連接埠監聽              serverSocket = new ServerSocket(4567);        //調用ServerSocket的accept()方法,接受用戶端所發送的請求,//如果用戶端沒有發送資料,那麼該線程就停滯不繼續              Socket socket = serverSocket.accept();              //從Socket當中得到InputStream對象              InputStream inputStream = socket.getInputStream();              byte buffer [] = new byte[1024*4];              int temp = 0;              //從InputStream當中讀取用戶端所發送的資料              while((temp = inputStream.read(buffer)) != -1){                  System.out.println(new String(buffer,0,temp));              }           } catch (IOException e) {              // TODO Auto-generated catch block              e.printStackTrace();           }            serverSocket.close();           } 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.