三、定製請求
瞭解了volley自帶的默認功能,覺得很方便吧,其實volley的強大遠遠不止於此。就像網絡上傳輸的數據通常有兩種格式,JSON和XML,那麼如果想要請求一條XML格式的數據該怎麼辦呢?
下面我們就來看下volley怎麼處理這種不常見的數據格式。
package com.example.VolleyDemo;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.*;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.Volley;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import static com.android.volley.Response.*;
public class XmlActivity extends Activity {
private TextView mXmlResult;
private StringBuffer mBuffer = new StringBuffer();
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xml);
mXmlResult = (TextView) findViewById(R.id.XmlTxt);
}
RequestQueue mQueue;
@Override
protected void onStart() {
super.onStart();
/********************4步驟********************/
//1.創建一個RequestQueue對象
mQueue = Volley.newRequestQueue(this);
//2.啓動RequestQueue
mQueue.start();
//3.創建一個XMLRequest
XMLRequest xmlRequest = new XMLRequest(
"http://flash.weather.com.cn/wmaps/xml/china.xml",
new Response.Listener<XmlPullParser>() {
@Override
public void onResponse(XmlPullParser response) {
try {
int eventType = response.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
String nodeName = response.getName();
if ("city".equals(nodeName)) {
String pName = response.getAttributeValue(0);
Log.d("TAG", "pName is " + pName);
mBuffer.append(pName);
}
break;
}
eventType = response.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mXmlResult.setText(mBuffer.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
Toast.makeText(XmlActivity.this, "網絡錯誤", Toast.LENGTH_SHORT).show();
}
});
//4.將XmlRequest對象添加到RequestQueue裏面
mQueue.add(xmlRequest);
/******************************************/
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mQueue!=null){
mQueue.cancelAll(this);
}
}
class XMLRequest extends Request<XmlPullParser> {
private final Listener<XmlPullParser> mListener;
public XMLRequest(int method, String url, Listener<XmlPullParser> listener,
ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
}
public XMLRequest(String url, Listener<XmlPullParser> listener, ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
@Override
protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
try {
String xmlString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlString));
return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (XmlPullParserException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(XmlPullParser response) {
mListener.onResponse(response);
}
}
}
其實很簡單,Volley提供了非常強的擴展機制,使得我們可以很輕鬆地定製出任意類型的Request。
XMLRequest也是繼承自Request類的,只不過這裏指定的泛型類是XmlPullParser,說明我們準備使用Pull解析的方式來解析XML。在parseNetworkResponse()方法中,先是將服務器響應的數據解析成一個字符串,然後設置到XmlPullParser對象中,在deliverResponse()方法中則是將XmlPullParser對象進行回調。
XMLRequest的用法和StringRequest幾乎是一模一樣的,我們先創建出一個XMLRequest的實例,並把服務器接口地址傳入,然後在onResponse()方法中解析響應的XML數據,最後將這個XMLRequest添加到RequestQueue當中。
參考:http://blog.csdn.net/guolin_blog/article/details/17612763