1. 程式人生 > >android網路通訊的六種方式

android網路通訊的六種方式

  手機作為一種通訊終端(MMS),伴隨著網路的升級而不斷的升級換代。1995年1G問世,手機只能進行基本的語音通訊,1996-1997年2G(GSM,CDMA)及其後的GPRS,EDGE等技術的快速發展,手機開始逐漸增加了資料服務功能。2009年開始,3G在全世界開始大規模佈置以及蘋果創造性開發新型蘋果手機。手機慢慢的變成網際網路的終端,從而帶動了一個新的時代--移動網際網路時代。因此現代手機通常都支援這些常用網路裝置,如WIFI,NFC,藍芽等。
Android是由網際網路巨頭Google帶頭開發的,因此對網路功能的支援是必不可少的。Google的應用層採用的是Java語言。所以JAVA支援的網路程式設計方式Android都支援,同時Google還引入了Apache 的HTTP擴充套件包。另外,針對WIFI,NFC,分別提供的單獨的開發API.

表1展示了Android SDK中的一些與網路有關的API包名
表1. Android SDK 網路包
包                      描述                                                               API Level
Java.net                        提供與聯網有關的類,包括流和資料包(datagram)sockets、Internet 協議和常見 HTTP 處理。該包是一個多功能網路資源。有經驗的 Java 開發人員可以立即使用這個熟悉的包建立應用程式。        1
java.io                        雖然沒有提供顯式的聯網功能,但是仍然非常重要。該包中的類由其他 Java 包中提供的 socket 和連線使用。它們還用於與本地檔案(在與網路進行互動時會經常出現)的互動        1
java.nio                        包含表示特定資料型別的緩衝區的類。適合用於兩個基於 Java 語言的端點之間的通訊。        1
org.apache.*        表示許多為 HTTP 通訊提供精確控制和功能的包。可以將 Apache 視為流行的開源 Web 伺服器。        1
android.net        除核心 java.net.* 類以外,包含額外的網路訪問 socket。該包包括 URI 類,後者頻繁用於 Android 應用程式開發,而不僅僅是傳統的聯網方面。        1
android.net.http        包含處理 SSL 證書的類。        1
android.net.wifi        包含在 Android 平臺上管理有關 WiFi(802.11 無線 Ethernet)所有方面的類。        1
android.telephony.gsm        包含用於管理和傳送 SMS(文字)訊息的類。一段時間後,可能會引入額外的包來來為非 GSM 網路提供類似的功能,比如 CDMA 或 android.telephony.cdma 等網路。        1
Android.net.sip        包含Andriod平臺上管理有關SIP協議如建立和迴應Voip的類        9
Android.nfc        包含所有用來管理近場通訊相關的功能類        9


在Android中幾種網路程式設計的方式:
(1)針對TCP/IP的Socket、ServerSocket
(2)針對UDP的DatagramSocket、DatagramPackage。這裡需要注意的是,考慮到Android裝置通常是手持終端,IP都是隨著上網進行分配的。不是固定的。因此開發也是有一點與普通網際網路應用有所差異的。
(3)針對直接URL的HttpURLConnection
(4)Google集成了Apache HTTP客戶端,可使用HTTP進行網路程式設計。針對HTTP,Google集成了Appache Http core和httpclient 4版本,因此特別注意Android不支援httpclient 3.x系列,而且目前並不支援Multipart(MIME),需要自行新增httpmime.jar
(5)使用Web Service。Android可以通過開源包如jackson去支援Xmlrpc和Jsonrpc,另外也可以用Ksoap2去實現Webservice
  (6) 直接使用WebView檢視元件顯示網頁。基於WebView 進行開發,Google已經提供了一個基於chrome-lite的Web瀏覽器,直接就可以進行上網瀏覽網頁。

一、我們先來看第一種,針對TCP/IP Socket、ServerSocket的形式。
TCP/IP是一種協議,是一種面向連線的、可靠的協議。Socket僅僅是對TCP、UDP網路介面的封裝,不涉及上層協議。TCP、UDP傳輸特性不同,分別適用於不同型別的應用層協議,其中TCP有連線,延時較長,能保證服務質量;UDP無連線,需要應用程式進行資料分包、延時短,效率高,資料包可能丟失或到達對端發生順序混亂。在Socket之上可以實現這些RFC標準的應用層協議,也可以自定義實現私有的應用層協議。

在JAVA程式設計中, 經常使用java.net和javax.net包來開發socket程式,下面列出所有常用的類,並簡單介紹。關於詳細的資訊請參看JAVA文件。

Java.net
Java.net.Socket                        客戶端連線使用的TCP socket
Java.net.DatagramSocket        客戶端和服務端共同使用的UDP socket
Java.net.ServerSocket        服務端TCP socket監聽埠
Java.netInetAddress                        IP地址封裝類
Java.net.DataGramPacket        通過DatagramSocket收發的資料包的封裝類,包括資料和對端的IP地址、UDP埠

Javax.net
Javax.net.SocketFactory                        客戶端連線使用的T CP socket
Javax.net.ServerSocketFactory        服務端TCP socket監聽埠
Javax.net.ssl.SSLSocketFactory        SSL客戶端Socket構造器
Javax.net.ssl.SSLServerFactory        SSL服務端監聽Socket構造器

示例程式碼: android+socket程式設計例項.rar

二、針對UDP的DatagramSocket、DatagramPackage
1.對於UDP服務端,首先啟動偵聽服務,然後得到資料包進行處理,組後根據獲得資料包進行反饋。
2.UDP socket沒有連線的概念,因此構造完成的DatagramSocket不會發出向對端的網路連線請求,在每一個傳送的UDP資料包中包含目的地址和埠。因為UDP資料不會在對端進行重新組包,因此一次傳送的資料長度必須加以限制。Socket.send(outputPacket);用於傳送一個數據包;socket.receive(inputPacket);用於接收一個數據包。



  

示例程式碼:
伺服器端:
public class UDPServer{
             public static void main(String[] args) throws Exception{
                     DatagramSocket udpSocket = new DatagramSocket(8000);
                     while(true){
                             try{
                                     // UDP資料讀取
                                     DatagramPacket packet = new DatagramPacket(new byte[512],512);
                                     udpSocket.receive(packet);
                                     String msg = new String(packet.getData()), 0,packet.getLength());
                                     System.out.println(msg);
                                     if(msg.equals("exit")){
                                             break;
                                     }
                                     
                                     // UDP資料傳送
                                     SimpleDateFormat f = new SimpleDateFormat("MMM dd,yyyy kk:mm:ss");
                                     String time = "現在的時間是:" + f.format(new Date());
                                     packet.setData(time.getBytes());
                                     udpSocket.send(packet);
                                     
                             }catch(Exception e){
                                     e.printStackTrace();
                             }
                     }
                     udpSocket.close();
             }
     }

客戶端:
public void client(){
             InetAddress remoteIP;
                try {
                        remoteIP = InetAddress.getByName("localhost");
                        DatagramSocket socket = new DatagramSocket();
                } catch (UnknownHostException e1) {
                        e1.printStackTrace();
                }
             
             BufferedReader wt = new BufferedReader (new InputStreamReader(System.in));
             System.out.println("input one line ,user \"exit\" to quit the server ");
             while(true){
                     try{
                             // 讀取輸入
                             String str = wt.readLine();
                             byte[] outputData = str.getBytes();
                             // UDP socket 資料傳送
                             DatagramPacket outputPacket = new DatagramPacket(outputData,outputData.length,remoteIP,8000);
                             socket.send(outputPacket);
                             if(str.equals("exit")){
                                     //udp 資料讀取
                                     DatagramPacket inputPacket = new DatagramPacket(new byte[512],512);
                                     socket.receive(inputPacket);
                                     System.out.println(new String(inputPacket.getData(),0,inputPacket.getLength()));
                                      
                             }
                     }catch(Exception e){
                             e.printStackTrace();
                     }
             }
             socket.close();
     }

三、針對直接URL的HttpURLConnection
這個就是把請求的方式從HttpClient換成HttpURLConnection就可以了。沒什麼可以說的,自己看看吧。

示例程式碼:無

四、Google集成了Apache HTTP客戶端,可使用HTTP進行網路程式設計
這個不多說了,網路程式設計,必須會的。自己看程式碼吧。服務端我使用三種方式:S2SH、只用Struts2、Servlet。客戶端就一種,只不過換個請求的URL。服務端和客戶端互動使用了兩種方式:XML、JSON,目前開放平臺返回的資料都是支援這兩種資料格式的。所以我也實現了這兩種資料格式。其實還有一種格式,就是google的protocal buffer,這種形式在國內用的人比較少,我也沒弄,感興趣的同學看我提供的文件,自己研究吧。注意把裡面的IP換成自己電腦的IP地址。

示例程式碼:
服務端:ServletTest1.rar、StrAnd.rar、WebAndroid.rar
客戶端:WebAndroidClient.rar

參考網址:
http://www.cnblogs.com/zhangdong ... /04/19/2020688.html

http://blog.csdn.net/woshisap/article/details/6621571
http://www.360doc.com/content/11/0521/01/4154133_118259561.shtml

注意:在只使用Struts2的伺服器端,可以這麼配置:
<package name="struts-main" extends="json-default" >   
      <action name="*UserAction" class="userAction" method="{1}">
         <result type="json"></result>
      </action>
  </package>
也可以這麼配置:
<package name="struts-main" extends="struts-default" >   
      <action name="*UserAction" class="userAction" method="{1}">
          <result name="register">/WEB-INF/page/register.jsp</result>
          <result name="save">/WEB-INF/page/index.jsp</result>       
      </action>
  </package>

       但是其實返回資料的時候都是封裝JSON字串,沒用到第一種形式的配置的功能。據說,用第一種配置方式,struts2可以自動把返回的資料封裝成JSON字串的形式,但是我沒測試成功。。。。我返現返回什麼格式還是什麼格式,並沒有把資料自動封裝成JSON返回。
    在使用S2SH的服務端,就不能用第一種方式配置。只能用第二種方式,然後服務端封裝JSON返回客戶端。如果用第一種方式配置,就會發生404錯誤。無法找到伺服器端。
    在使用Servlet的服務端,可以通過下面這種方式設定返回型別,但是其實沒用,你設定了,它也不返回。你只能自己封裝XML檔案或者JSON字串,然後返回。
response.setContentType("application/json;charset=utf-8");

(5)使用Web Service
我之前只聽說過什麼事webservice,因此主要是參考下面文章實現的DEMO,他給出了一些例項程式碼,不全,我給基本補全了。顯示天氣資訊我都在LOG輸出了,沒有顯示在介面上,如果大家覺得不爽,可以把資訊直接顯示在介面上就可以了。因為我被這個問題困擾了2天,弄的很崩潰,所以就沒繼續弄。大家自己看吧。
那麼什麼是webService呢?,它是一種基於SAOP協議的遠端呼叫標準,通過webservice可以將不同作業系統平臺,不同語言,不同技術整合到一起。在Android中,第三方公司提供了基於webservice的jar包:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar
http://www.cnblogs.com/zhangdong ... /04/19/2020688.html

http://www.cnblogs.com/ghj1976/archive/2011/04/26/2028904.html
示例程式碼:SoapAndroidTeset.rar、sserEx09.rar

(6) 直接使用WebView檢視元件顯示網頁

這就是使用webview顯示網頁的問題,比較容易,大家自己看吧。我就不貼例項程式碼了。