Android 學習筆記之Volley(七)實現Json數據加載和解析...


 

 

學習內容:

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;
        }
    }
}

 

 

 



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM