Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android網絡編程(總結)

Android網絡編程(總結)

編輯:關於Android編程



概述

首先,應該了解的幾個問題:

1)Android平台網絡相關API接口

a) java.net.*(標准Java接口)

 

java.net.*提供與聯網有關的類,包括流、數據包套接字(socket)、Internet協議、常見Http處理等。比如:創建URL,以及URLConnection/HttpURLConnection對象、設置鏈接參數、鏈接到服務器、向服務器寫數據、從服務器讀取數據等通信。這些在Java網絡編程中均有涉及。

b) Org.apache接口

對於大部分應用程序而言JDK本身提供的網絡功能已遠遠不夠,這時就需要Android提供的Apache HttpClient了。它是一個開源項目,功能更加完善,為客戶端的Http編程提供高效、最新、功能豐富的工具包支持。

c)Android.net.*(Android網絡接口)

常常使用此包下的類進行Android特有的網絡編程,如:訪問WiFi,訪問Android聯網信息,郵件等功能。

 

2)網絡架構主要有兩種模式B/S,C/S

B/S----》就是浏覽器/服務器端模式了,通過應用層的HTTP協議通信,不需要特定客戶端軟件,而是需要統一規范的客戶端,簡而言之就是Android網絡浏覽器(如chrome,UcWeb,QQ浏覽器等等)訪問web服務器端的方式了。

C/S-----》就客戶端/服務器端模式,通過任意的網絡協議通信,需要特定的客戶端軟件。

3)服務器端返回客戶端的內容有三種方式:

a)以HTML代碼的形式返回。

b)以XML字符串的形式返回,做Android開發時這種方式比較多。返回的數據需要通過XML解析(SAX、DOM,Pull,等)器進行解析(必備知識)。

c)以json對象的方式返回。

 

Android的網絡編程分為2種:基於http協議的,和基於socket的

一、HTTP協議

基於TCP/IP協議之上的協議

1.1HttpURLConnection連接URL
1)創建一個URL對象

URL url = new URL(http://www.baidu.com);

2)利用HttpURLConnection對象從網絡中獲取網頁數據

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

3)設置連接超時

conn.setConnectTimeout(6*1000);

4)對響應碼進行判斷

if (conn.getResponseCode() != 200) //從Internet獲取網頁,發送請求,將網頁以流的形式讀回來

throw new RuntimeException("請求url失敗");

5)得到網絡返回的輸入流

InputStream is = conn.getInputStream();
6)String result = readData(is, "GBK"); //文件流輸入出文件用outStream.write
7)conn.disconnect();

總結:
--記得設置連接超時,如果網絡不好,Android系統在超過默認時間會收回資源中斷操作.
--返回的響應碼200,是成功.
--在Android中對文件流的操作和Java SE上面是一樣的.
--在對大文件的操作時,要將文件寫到SDCard上面,不要直接寫到手機內存上.
--操作大文件是,要一遍從網絡上讀,一遍要往SDCard上面寫,減少手機內存的使用.這點很重要,面試經常會被問到.
--對文件流操作完,要記得及時關閉.


1.2向服務器端發送請求參數
步驟:
1)創建URL對象:URL realUrl = new URL(requestUrl);
2)通過HttpURLConnection對象,向網絡地址發送請求

HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
3)設置容許輸出:conn.setDoOutput(true);
4)設置不使用緩存:conn.setUseCaches(false);
5)設置使用POST的方式發送:conn.setRequestMethod("POST");
6)設置維持長連接:conn.setRequestProperty("Connection", "Keep-Alive");
7)設置文件字符集:conn.setRequestProperty("Charset", "UTF-8");
8)設置文件長度:conn.setRequestProperty("Content-Length", String.valueOf(data.length));
9)設置文件類型:conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

10)設置HTTP請求頭

conn.setRequestProperty("Accept“,” image/gif,image/jpeg,image/pjpeg,image/pjpeg,application/x-shockwave-flash,application/xaml+xml,application/vnd.ms-xpsdocument,application/x-ms-xbap,application/x-ms-application,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/*");

設置語言:conn.setRequestProperty("Accept-Language“,"zh-CN");

conn.setRequestProperty("

conn.setRequestProperty("
11)以流的方式輸出.
總結:
--發送POST請求必須設置允許輸出
--不要使用緩存,容易出現問題.
--在開始用HttpURLConnection對象的setRequestProperty()設置,就是生成HTML文件頭.

1.3.向服務器端發送xml數據(也稱為實體Entity)
XML格式是通信的標准語言,Android系統也可以通過發送XML文件傳輸數據.
1)將生成的XML文件寫入到byte數組中,並設置為UTF-8:byte[] xmlbyte = xml.toString().getBytes("UTF-8");
2)創建URL對象,並指定地址和參數:URL url = new URL(http://localhost:8080/itcast/contanctmanage.do?method=readxml);
3)獲得鏈接:HttpURLConnection conn = (HttpURLConnection) url.openConnection();
4)設置連接超時:conn.setConnectTimeout(6* 1000);
5)設置允許輸出conn.setDoOutput(true);
6)設置不使用緩存:conn.setUseCaches(false);
7)設置以POST方式傳輸:conn.setRequestMethod("POST");
8)維持長連接:conn.setRequestProperty("Connection", "Keep-Alive");
9)設置字符集:conn.setRequestProperty("Charset", "UTF-8");
10)設置文件的總長度:conn.setRequestProperty("Content-Length", String.valueOf(xmlbyte.length));
11)設置文件類型:conn.setRequestProperty("Content-Type","text/xml; charset=UTF-8");
12)以文件流的方式發送xml數據:outStream.write(xmlbyte);
總結:
--我們使用的是用HTML的方式傳輸文件,這個方式只能傳輸一般在5M一下的文件.
--傳輸大文件不適合用HTML的方式,傳輸大文件我們要面向Socket編程.確保程序的穩定性
--將地址和參數存到byte數組中:byte[] data = params.toString().getBytes();

1.4 利用Apache的HttpClient實現Android客戶端發送實體Entity

以上為直接利用HTTP協議來實現的,其實Android已經集成了第三方開源項目-------org.apache.http.client.HttpClient,可以直接參考它提供的API使用。

HTTP clients encapsulate a smorgasbord of objects required to execute HTTP requests while handling cookies, authentication, connection management, and other features. Thread safety of HTTP clients depends on the implementation and configuration of the specific client.

使用POST方法進行參數傳遞時,需要使用NameValuePair來保存要傳遞的參數。另外,還需要設置所使用的字符集。

二、基於Socket通信

Socket編程比基於URL的網絡編程提供了更高的傳輸效率,更強大的功能和更靈活的控制。在Java中已經是層次最低的網絡編程接口,在Java中要直接操作協議中更低的層次,那就只有使用JNI了,那基本屬於本地語言的范疇。

\\

 

三、其它網絡相關技術

 

3.1、Android WebView控件

在android app 中嵌入網頁的形式。

此外,通過webview可以實現HTML<------->javascript<-------->Android Java 交互,訪問本地手機硬件。

例如:

1) webview.addJavascriptInterface(Objectobj,StringinterfaceName))方法, 讓Java方法可以在javascript中被調用;

 

void addJavascriptInterface(Objectobj,StringinterfaceName) Use this function to bind an object to JavaScript so that the methods can be accessed from JavaScript. 2)Java中調用Javascript腳本中的方法

 

webview.loadUrl("javascript:show('"+json+"')");//調用js的show方法


3.2基於SOAP協議與Webservice網絡交互 ------------KSoap2
簡單對象訪問協議,簡單對象訪問協議(SOAP)是一種輕量的、簡單的、基於 XML 的協議。

通過第三方提供的架包ksoap2-Android-assembly-2.4-jar-with-dependencies.jar,我們可以向服務器進行請求調用自己需要的服務。

3.3 實現服務器推送

通過建立持久連接的方法,服務器端發送信息給手機Android用戶。

方法一:MQTT協議(實例android+php)

1、服務器端需下載安裝IBM的Really Small Message Broker (RSMB)(MQTT協議代理),並運行broker;

下載地址:http://www.alphaworks.ibm.com/tech/rsmb

2、PHP服務器端使用SAM 針對MQTT寫的PHP庫(下載鏈接為Tokudu PHPMQTT通信項目),其中send_mqtt.php是一個通過POST接收消息並且通過SAM將消息發送給RSMB的PHP腳本;

3、實例下載:

說明:http://tokudu.com/2010/how-to-implement-push-notifications-for-android/

android客戶端:https://github.com/tokudu/AndroidPushNotificationsDemo

php服務器端:https://github.com/tokudu/PhpMQTTClient

 

方法二:XMPP協議(實例android+jsp)

XMPP : The Extensible Messaging and Presence Protocol (可擴展通訊和表示協議) XMPP 以 Jabber 協議為基礎,而 Jabber 是即時通訊中常用的開放式協議。

下載地址:http://sourceforge.net/projects/androidpn/files/

解壓服務器端,點擊bin/run.bat運行,訪問:http://127.0.0.1:7070/index.do,就可以看服務器端的管理頁面,用這個管理頁面,就要向客戶端push消息。


方法三:使用APNS (Android Push Notification Service)

http://www.push-notification.org/

APNS (Android Push Notification Service) 是一種在 android 上輕松實現 push notification 的功能的解決方案. 只需申請一個 API Key, 經過簡單的步驟即可實現 push notification 的功能.

 

 

3.4 PhoneGap

提到移動3G時代網絡應用,不得不提一下PhoneGap了。

phonegap利用HTML,CSS,javascript, 支持Android、iPhone,Windows Phone、Palm OS、Sybian....

如果考慮開發一款應用,適用於大多數智能手機,phonegap是可以考慮的開發框架之一。

 

Android各種網絡協議,mark一下下次不用再翻以前的工程

Soap協議

 

[java]view plaincopy  
  1. publicstaticDoctordoctorLogin(StringloginName,Stringpassword,Stringterminal)throwsAppException{
  2. Doctoruser=null;
  3. StringmethodName="doctorLogin";
  4. try{
  5. //創建soap對象
  6. SoapObjectsoapObject=newSoapObject(Constant.loginNamespace,methodName);
  7. //添加參數
  8. soapObject.addProperty("arg0",loginName);
  9. soapObject.addProperty("arg1",password);
  10. soapObject.addProperty("arg2",terminal);
  11.  
  12. //設置連接參數
  13. HttpTransportSEhse=newHttpTransportSE(Constant.loginUrl,Constant.OverTime);
  14. hse.debug=true;
  15. SoapSerializationEnvelopesse=newSoapSerializationEnvelope(SoapEnvelope.VER11);
  16. sse.bodyOut=soapObject;
  17. sse.dotNet=false;
  18. hse.call(null,sse);
  19. Stringresult=sse.getResponse().toString();
  20.  
  21. //解析結果
  22. JSONObjectjsonObject=newJSONObject(result);
  23. BooleanresultTag=jsonObject.getBoolean("resultTag");
  24. if(resultTag){
  25. //使用Gson實現對Json字符的解析
  26. Stringuserinfo=jsonObject.getString("doctor");
  27. GsonBuilderbuilder=newGsonBuilder();
  28. Gsongson=builder.create();
  29. user=gson.fromJson(userinfo,Doctor.class);
  30.  
  31. }else{
  32. StringexMsg=jsonObject.getString("msg");
  33. loginException=exMsg;
  34. AppExceptionmAppException=newAppException(exMsg);
  35. throwmAppException;
  36. }
  37. }catch(Exceptione){
  38. AppExceptionmAppException=newAppException(e);
  39. throwmAppException;
  40. }
  41. returnuser;
  42. }

http 協議與服務器通信

以下是上次用到的mark一下

 

[java]view plaincopy  
  1. publicListgetDoctoradviceList(StringpersionID,StringbeginTime,StringendTime)throwsException{
  2. Listlist=null;
  3. StringBuffermBuffer=newStringBuffer();
  4. mBuffer.append(persionID);
  5. mBuffer.append("/");
  6. mBuffer.append(beginTime.replace("","%20"));
  7. if(D)Log.d(TAG,"beginTime"+beginTime);
  8. mBuffer.append("/");
  9. mBuffer.append(endTime.replace("","%20"));
  10. if(D)Log.d(TAG,"endTime"+endTime);
  11. HttpGetrequstGet=newHttpGet(Constant.getDoctoradvicAddress+mBuffer.toString());
  12. requstGet.setHeader("Accept","application/json");
  13. requstGet.setHeader("Content-type","application/json;charset=UTF-8");
  14. HttpResponsemResponse=newDefaultHttpClient().execute(requstGet);
  15. //獲取網絡連接狀態
  16. intintId=mResponse.getStatusLine().getStatusCode();
  17. StringresponsStr=null;
  18. HttpEntitymEntity=mResponse.getEntity();
  19. if(mEntity!=null){
  20. InputStreammInputStream=mEntity.getContent();
  21. responsStr=StrUtil.convertStreamToString(mInputStream);
  22. if(D)Log.d(TAG,"醫生建議查詢:"+responsStr);
  23. if(intId==200){
  24. GsonBuildergsonb=newGsonBuilder();
  25. Gsongson=gsonb.create();
  26. list=gson.fromJson(responsStr,newTypeToken>(){}.getType());
  27. }else{
  28. GsonBuildergsonb=newGsonBuilder();
  29. Gsongson=gsonb.create();
  30. Faultf=gson.fromJson(responsStr,Fault.class);
  31. thrownewAppException(f.message);
  32. }
  33. }
  34.  
  35. returnlist;
  36. }

 

本示例以Servlet為例,演示Android與Servlet的通信。

眾所周知,Android與服務器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post兩種方式。至於Socket通信會在以後的博文中介紹。
 

HTTP協議簡介:

HTTP (Hypertext Transfer Protocol ),是Web聯網的基礎,也是手機聯網常用的協議之一,HTTP協議是建立在TCP協議之上的一種協議。

HTTP連接最顯著的特點是客戶端發送的每次請求都需要服務器回送響應,在請求結束後,會主動釋放連接。從建立連接到關閉連接的過程稱為“一次連接”。 在HTTP 1.0中,客戶端的每次請求都要求建立一次單獨的連接,在處理完本次請求後,就自動釋放連接。 在HTTP 1.1中則可以在一次連接中處理多個請求,並且多個請求可以重疊進行,不需要等待一個請求結束後再發送下一個請求。

由於HTTP在每次請求結束後都會主動釋放連接,因此HTTP連接是一種“短連接”、“無狀態”,要保持客戶端程序的在線狀態,需要不斷地向服務器發起連接請求。通常的做法是即使不需要獲得任何數據,客戶端也保持每隔一段固定的時間向服務器發送一次“保持連接”的請求,服務器在收到該請求後對客戶端進行回復,表明知道客戶端“在線”。若服務器長時間無法收到客戶端的請求,則認為客戶端“下線”,若客戶端長時間無法收到服務器的回復,則認為網絡已經斷開。

基於HTTP1.0協議的客戶端在每次向服務器發出請求後,服務器就會向客戶端返回響應消息,在確認客戶端已經收到響應消息後,服務端就會關閉網絡連接。在這個數據傳輸過程中,並不保存任何歷史信息和狀態信息,因此,HTTP協議也被認為是無狀態的協議。

  HTTP1.1和HTTP1.0相比較而言,最大的區別就是增加了持久連接支持。當客戶端使用HTTP1.1協議連接到服務器後,服務器就將關閉客戶端連接的主動權交還給客戶端;也就是說,只要不調用Socket類的close方法關閉網絡連接,就可以繼續向服務器發送HTTP請求。

HTTP連接使用的是“請求—響應”的方式(2次握手),不僅在請求時需要先建立連接,而且需要客戶端向服務器發出請求後,服務器端才能回復數據。而Socket連接在雙方建立起連接後就可以直接進行數據的傳輸

 

  HTTP協議的特點:

支持B/S及C/S模式;

簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。

靈活:HTTP 允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type 加以標記;

無狀態:HTTP 協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。

 

HTTP協議請求方法:

請求行中包括了請求方法,解釋如下:

GET 請求獲取Request-URI 所標識的資源;

POST 在Request-URI 所標識的資源後附加新的數據;

HEAD 請求獲取由Request-URI 所標識的資源的響應消息報頭

PUT 請求服務器存儲一個資源,並用Request-URI 作為其標識

DELETE 請求服務器刪除Request-URI 所標識的資源;

TRACE 請求服務器回送收到的請求信息,主要用於測試或診斷

CONNECT 保留將來使用

OPTIONS 請求查詢服務器的性能,或者查詢與資源相關的選項和需求

 

Get與Post請求區別:

Post請求可以向服務器傳送數據,而且數據放在HTML HEADER內一起傳送到服務端URL地址,數據對用戶不可見。而get是把參數數據隊列加到提交的URL中,值和表單內各個字段一一對應, 例如(http://www.baidu.com/s?w=%C4&inputT=2710)

get 傳送的數據量較小,不能大於2KB。post傳送的數據量較大,一般被默認為不受限制。但理論上,IIS4中最大量為80KB,IIS5中為100KB。

get安全性非常低,post安全性較高。

項目結構圖:

\

 

get方式:

get機制用的是在URL地址裡面通過?號間隔,然後以name=value的形式給客戶端傳遞參數。所以首先要在Android工程下的AndroidGetTest.java中onCreate方法定義好其URL地址以及要傳遞的參數,然後通過URL打開一個HttpURLConnection鏈接,此鏈接可以獲得InputStream字節流對象,也是往服務端輸出和從服務端返回數據的重要過程,而若服務端response.getInputStream.write()往andorid返回信息時候,就可以通過InputStreamReader作轉換,將返回來的數據用BufferReader顯示出來。

具體代碼如下:

Servlet端接收數據並返回通知:

 

\

Android端發送消息並接收Servlet返回的消息:

\

 

post方式:

post傳輸方式不在URL裡傳遞,也正好解決了get傳輸量小、容易篡改及不安全等一系列不足。主要是通

過對HttpURLConnection的設置,讓其支持post傳輸方式,然後在通過相關屬性傳遞參數(若需要傳遞中文字符,則可以通過URLEncoder編碼,而在獲取端采用URLDecoder解碼即可)

 

\

\

   

其中通信的過程中需要文件的上傳、下載會以 IO 流的方式傳輸

下載一張圖片


private void getNetWorkImage() {
    new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                URL imageUrl = new URL("https://www.baidu.com/img/bdlogo.png");
                HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
                conn.setConnectTimeout(10000);
                conn.setRequestMethod("GET");
                if(conn.getResponseCode() == 200) {
                    InputStream is = conn.getInputStream();
                    Bitmap bitmap = BitmapFactory.decodeStream(is);
                    Message msg = mHandle.obtainMessage();
                    msg.what = 1;
                    msg.obj = bitmap;
                    mHandle.sendMessage(msg);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

}

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved