學習內容:
1.使用Volley實現異步加載Json數據...
Volley的第二大請求就是通過發送請求異步實現Json數據信息的加載,加載Json數據有兩種方式,一種是通過獲取Json對象,然后對對象進行解析,從而獲取Json數據,另一種方式則是通過獲取JsonArray的方式來對Json數據進行解析,其實就是Json數組...由於Json數據格式的不同,因此也就有了這兩種方式...
因此實現類也就成為了兩個JsonObjectRequest.java和JsonArrayRequest.java,他們都 extends JsonRequest,而JsonRequest繼承了Request類,重寫了其中內部的一些方法...因為獲取Json對象,提交這個請求已經是一個確定好的類型,因此需要對父類中的一些方式進行重寫...Request只是為更多的請求方式提供了一個父類,其他類型的請求,需要使用新的類進行繼承,重寫,然后子類再充當父類,用新的子類進行繼承和重寫...從而實現了良好的擴展....
那么JsonRequest為什么沒有實現parseNetWorkResponse想必也就不用說了,對外提供接口,方便擴展和實現...
我們先看看第一種,使用Volley獲取JsonObject,從而解析獲取Json數據...
1.JsonObjectRequest.java
這里的源碼就非常的簡單了,沒什么太多可說的...關鍵還是看如何調用...
package com.android.volley.toolbox; import com.android.volley.NetworkResponse; import com.android.volley.ParseError; import com.android.volley.Response; import com.android.volley.Response.ErrorListener; import com.android.volley.Response.Listener; import org.json.JSONException; import org.json.JSONObject; import java.io.UnsupportedEncodingException; public class JsonObjectRequest extends JsonRequest<JSONObject> { //指定提交方式和url來創建一個請求對象... public JsonObjectRequest(int method, String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener) { super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener, errorListener); } //通過url的形式來建立一個請求對象... public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener) { this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest, listener, errorListener); } @Override protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) { try { String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); //按照指定字符集解析.. return Response.success(new JSONObject(jsonString),//返回成功數據... HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } catch (JSONException je) { return Response.error(new ParseError(je)); } } }
調用的方式我們還是通過例子來完成...這里我們通過請求來獲取Json數據...
http://192.168.199.172:8080/JSP/Json_1.txt是這個樣子的...簡單的Json數據...
{ "user":[ {"userid":"1","username":"darker","userpassword":"49681888"}, {"userid":"2","username":"darker_1","userpassword":"49681888"}, {"userid":"3","username":"darker_2","userpassword":"49681888"} ] }
下面通過請求完成調用,獲取其中的內容...
package com.example.oop; import com.android.volley.RequestQueue; import com.android.volley.toolbox.Volley; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } public void init(){ RequestQueue queue=Volley.newRequestQueue(MainActivity.this); //這里沒有重寫錯誤方法...正常來說是需要重寫的... mqueue.add(new JsonObjectRequest(Method.GET,"http://192.168.199.172:8080/JSP/Json_1.txt",url,new Listener<JSONObject>(){ @Override public void Response(JSONObject response){ //這里我們可以看到我們獲取的就是JsonObject了...我們可以在這里進行解析,從而獲取想要的數據... List<HasnMap<String,String>>list=new ArrayList<HashMap<String,String>>(); String s[]=new String[]{"userid","username","userpassword"}; try{ JSONArray array=response.getJSONArray("user"); for(int i=0;i<array.size();i++){ JSONObject object=array.opt(i); Map<String,String>map=new HashMap<String,String>(); for(String str:s){ map.put(str,object.get(str)); } list.add(map); for(int i=0;i<list.size();i++){ for(int j=0;j<Json_id.length;j++){ System.out.println(list.get(i).get(Json_id[j])); } } } }catch(Exception e){} } })); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
通過Json對象,來解析Json數據的方式其實有很多種方式,這里我只列舉了一個,通過把JsonObject轉化成JsonArray的形式,然后對數組進行遍歷,從而獲取每一個數據信息...更多的方式我在博客中也進行了書寫,大家可以去看看Android學習筆記之Json的使用...這是第一種通過獲取JsonObject從而獲取Json數據信息的...
第二種方式:
2.JsonArrayRequest.java
源碼也就這點玩意...不是很難理解...
package com.android.volley.toolbox; import com.android.volley.NetworkResponse; import com.android.volley.ParseError; import com.android.volley.Response; import com.android.volley.Response.ErrorListener; import com.android.volley.Response.Listener; import org.json.JSONArray; import org.json.JSONException; import java.io.UnsupportedEncodingException; public class JsonArrayRequest extends JsonRequest<JSONArray> { //這里只有一種方式,直接通過url來建立一個JsonArray請求對象... public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener) { super(Method.GET, url, null, listener, errorListener); } @Override protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) { try { String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); return Response.success(new JSONArray(jsonString), HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } catch (JSONException je) { return Response.error(new ParseError(je)); } } }
看一下具體的調用過程...
http://192.168.199.172:8080/JSP/JSON.txt的數據信息如下..
[ {"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"}, {"firstName":"Jason","lastName":"Hunter","email":"bbbb"}, {"firstName":"Elliotte","lastName":"Harold","email":"cccc"} ]
主函數的調用過程...有一些包沒有引入,到時候書寫時編譯器會自動引入的...
package com.example.oop; import com.android.volley.RequestQueue; import com.android.volley.toolbox.Volley; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; public class MainActivity extends Activity{ String url="http://192.168.199.172:8080/JSP/JSON.txt"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } public void init(){ RequestQueue queue=Volley.newRequestQueue(MainActivity.this); mqueue.add(new JsonArrayRequest(url, new Listener<JSONArray>() { @Override public void OnResponse(JsonArray response){ //TODO Auto-generated method stub try{ for(int i=0;i<response.length;i++){ JsonObject object=(JsonObject)response.opt(i); Map<String,Object>map=new HashMap<String,Object>(); for(String str:s){ map.put(str,object.get(str)); } list.add(map); } for(int i=0;i<list.size();i++){ for(int j=0;j<s.length;j++){ System.out.println(list.get(i).get(s[j])); } } }catch(Exception e){} } }, new ErrorListener() { @Override public void onErrorResponse(VolleyError error){ //TODO Auto-generated method stub System.out.println(error.toString()); } })); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
這里當請求成功之后,獲取到的響應就是JsonArray對象了...然后通過遍歷就直接能夠獲取到JsonArray里保存的數據信息了...這就是解析的另一種方式...直接獲取Json數組...從而獲取數據信息...
JsonArrayRequest方式和JsonObjectRequest方式模式基本是相同的...只是對Json的數據格式要求並不一樣...只需在Json的格式上發生以下簡單的變化...
JsonArrayRequest請求的Json數據格式[{},{}]...返回的形式是Json數組..
JsonObjectRequest請求的Json數據格式["名稱":[{},{}]]...返回的形式是Json對象..
這樣就完成了Json數據的獲取+解析..獲取過程由Volley實現,解析由我們去實現...
最后我們來看一下父類的源代碼...
3.JsonRequest.java
源代碼其實也非常的簡單...
package com.android.volley.toolbox; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.Response.ErrorListener; import com.android.volley.Response.Listener; import com.android.volley.VolleyLog; import java.io.UnsupportedEncodingException; public abstract class JsonRequest<T> extends Request<T> { /** Charset for request. */ private static final String PROTOCOL_CHARSET = "utf-8"; //默認字符集.. /** Content type for request. */ private static final String PROTOCOL_CONTENT_TYPE = String.format("application/json; charset=%s", PROTOCOL_CHARSET); //協議內容的類型... private final Listener<T> mListener; //成功監聽... private final String mRequestBody; //請求實體... //通過url構造請求對象.. public JsonRequest(String url, String requestBody, Listener<T> listener, ErrorListener errorListener) { this(Method.DEPRECATED_GET_OR_POST, url, requestBody, listener, errorListener); } //通過指定方式+url來構造請求對象... public JsonRequest(int method, String url, String requestBody, Listener<T> listener, ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; mRequestBody = requestBody; } //請求的分發... @Override protected void deliverResponse(T response) { mListener.onResponse(response); } //解析請求的抽象方法,使JsonArrayRequest和JsonObjectRequest去實現.. @Override abstract protected Response<T> parseNetworkResponse(NetworkResponse response); //獲取Post請求中實體內容的類型.. @Override public String getPostBodyContentType() { return getBodyContentType(); } //獲取Post請求的實體部分... @Override public byte[] getPostBody() { return getBody(); } //指定內容類型... @Override public String getBodyContentType() { return PROTOCOL_CONTENT_TYPE; } //獲取實體內容的具體過程... @Override public byte[] getBody() { try { return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET); } catch (UnsupportedEncodingException uee) { VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", mRequestBody, PROTOCOL_CHARSET); return null; } } }