學習筆記(六) 網路程式設計與資料處理
廢話不多說啦,我們直接學習Android中最常使用的網路技術。
在請求網路之前,我們需要在AndroidManifest中宣告訪問網路的許可權:
uses-permission android:name="android.permission.INTERNET"/>
-HttpURLConnection
在Android上傳送HTTP請求的方式一般有兩種,HttpURLConnection和HttpClient,但是老師說HttpClient已經被Google棄用了,而HttpURLConnection能夠更好的處理網頁資料,並且可以減少耗電量。
- 獲得HttpURLConnection的例項
在獲取例項之前,我們需要一個URL物件,將目標的網路地址傳入,然後呼叫Url的openConnection()方法。
URL url=new URL("http://www.baidu.com");
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
至於問什麼要呼叫url的openConnection()方法,Android原始碼說是這個方法通過url返回一個指向資源的連線,所以還要進行強制轉型;
還要設定HTTP請求所使用的方式,在學習Html時,學到了GET和POST兩種方式,其中GET是從伺服器端獲取資料,POST是從伺服器端傳送資料,而且GET方式中表單的附加資訊會出現在URl上,相比於POST會不安全。
connection.setConnectTimeout(8000);//設定連線超時時間
connection.setReadTimeout(8000); //設定讀取超時時間
connection.connect();//開啟http連線
下面就是請求baidu資料的例項:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
//請求網路資料,需要申請許可權
data = requestData(url);
}
}).start();
}
private String requestData(String url_String) { //第一種方法
try {
String result=null;
URL url=new URL(url_String);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");//設定http請求所使用的方法
connection.setConnectTimeout(8000);//設定連線超時時間
connection.setReadTimeout(8000); //設定讀取超時時間
connection.connect();//開啟http連線
int response= connection.getResponseCode();//獲取響應狀態嘛
if(response== HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();//獲取伺服器返回的輸入流
Reader reader = new InputStreamReader(inputStream, "utf-8");
char[] buffer = new char[1024];
reader.read(buffer);//將reader讀到的資料放到char陣列中
result=new String(buffer);
}
else if(response== HttpURLConnection.HTTP_NOT_FOUND){
result="304 NOT FOUND!";
}
else{
result="Error!!";
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this,"非法網址",Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
finally {
connection.disconnect();//關閉http連線
}
return null;
}
因為獲取網路資料是一個同步操作,所以我們需要在一個子執行緒中去完成耗時操作;
除了使用執行緒,Android還提供一個很好的工具類——AsyncTask,但是它的實現原理還是基於非同步訊息處理機制。AsyncTask是一個抽象類,所以使用它必須用一個子類去繼承,其中必須要重寫的三個方法:onPreExecute() ;doInBackground(String[] params);
onPostExecute(String s);
分別對應三個不同的操作,第一個是在子執行緒之前,即在主執行緒中的操作;第二個是全部在子執行緒中執行;第三個是在子執行緒之後,進行的相關操作;
所以,使用AsyncTask會使我們方便很多,不需要在去考慮非同步訊息處理機制了。
-解析XML格式資料
通過上面的requestData()方法,我們得到了xml資料,但是隻有將資料解析之後才能得到我們想要的資料。
- SAX解析方式
private void parseXML_WithSAX(String xmlData) { //將SAX方式解析XML
try {
//先建立工程,在建立一個解析器,然後再有一個xml讀取器,固定的步驟
SAXParserFactory factory=SAXParserFactory.newInstance();
XMLReader xmlReader=factory.newSAXParser().getXMLReader();
SAX_Handler sax_handler=new SAX_Handler();
//將ContentHandler的例項設定到XMLReader中
xmlReader.setContentHandler(sax_handler);
//開始執行解析,
xmlReader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
e.printStackTrace();
}
}
String xmlData就是requestData()所返回的xml資料。
- Pull解析方式
Pull方法相對與SAX方法有點複雜。
private void requestXML_Pull(String data) { //用Pull方式解析XML
try {
XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser=factory.newPullParser();
xmlPullParser.setInput(new StringReader(data));
int eventType=xmlPullParser.getEventType();
String id="";
String item="";
while(eventType!=XmlPullParser.END_DOCUMENT){
String nodename=xmlPullParser.getName();
switch (eventType){
//開始解析某個節點
case XmlPullParser.START_TAG:
if("id".equals(nodename)){
id=xmlPullParser.nextText();
}else if("item".equals(nodename)){
item=xmlPullParser.nextText();
}
break;
case XmlPullParser.END_TAG:
if("app".equals(nodename)){
Log.i("TAG","id:"+id);
Log.i("TAG","item:"+item);
}
break;
default:break;
}
eventType=xmlPullParser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
}
setInput()方法是將伺服器返回的XML資料傳入,並開始解析。通過getEventType()可以得到當前的解析事件,通過while迴圈進行不斷的解析,getItem()方法是得到當前結點的名字,若結點不是結束節點,next()獲取下一個節點;若節點滿足相應的條件,則呼叫nextText()方法獲取節點中具體的內容。
- 解析JSON格式資料
比起XML,JSON主要優勢是在於它的體積更小,在網路上傳輸的時候可以更省流量。
解析JSON的方法有很多,可以使用官方提供的JSONObject,也可以使用Google的GSON。
private void requestJSON(String xml_json) {//測試JSON
try {
result="";
JSONArray jsonArray=new JSONArray(xml_json);
for(int i=0;i<jsonArray.length();i++){
JSONObject jsonobject=jsonArray.getJSONObject(i);
String id=jsonobject.getString("id");
String name=jsonobject.getString("name");
String version=jsonobject.getString("version");
result = "id:"+id+",name:"+name+",version:"+version+result;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
這裡是解析JSON資料中的id和version,通過requestData()從伺服器獲得返回的JSON資料,然後資料傳入一個JSON陣列中,通過JSONObject物件的getString()方法,返回所對應的資料。
GSON解析JSON資料
Google提供了一個非常簡單的工具,它可以將一段JSON格式的字串自動對映成一個物件,從而不需要我們在去解析。
使用GSONFormat工具(大家可以自行百度),將我們的JSON資料可以自動對映成一個物件,通過物件的方法我們可以得到JSON中的任何資料,非常方便。
Gson gson=new Gson();
JSon_Bean jSon_bean=gson.fromJson(result,JSon_Bean.class);
JSON_Bean是json資料所影射的類,通過fromJson()方法可以獲得物件,從而可以操作JSON中的所有資料。