Android應用中網絡請求庫Volley的使用


上文,這次來說一下如何使用Volley,會給出一些范例,和原理

Volley使用 StringRequest

// 初始化一個請求隊列,RequestQueue是volley庫的類
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.baidu.com";
//定義一個字符串型請求隊列,需要傳遞4個參數分別是:url, 請求的方式(get, post..),響應成功的處理函數匿名對象, 相應出錯時候的處理函數匿名對象
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        // Display the first 500 characters of the response string.
mTextView.setText("Response is: "+ response.substring(0,500));
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        mTextView.setText("That didn't work!");
    }
});
//添加到請求隊列中,默認就開始了網絡請求
queue.add(stringRequest);

按照Volley的設計規則,程序要只要創建一個RequestQueue,並傳遞一個Request對象行了。RequestQueue維護這一些正在訪問網絡的線程的運行,讀寫緩存,獲取網絡請求的返回等事務。Request對象會再收到數據后進行解析,而RequestQueue還會負責將解析過的數據返回給主線程(UI線程),以便於你將數據在UI控件中展示等。

要使用Volley,必須在應用的Menifest文件中聲明android.permission.INTERNET的權限。

Volley發送網絡的過程解析

要想在代碼中獲取一個RequestQueue,默認可以使用Volley.newRequestQueue方法來完成,如上述代碼所示。當然你也可以自己定義一個你自己的RequestQueue。從上面的代碼看出,當Request對象創建好后,你只要調用RequestQueue的add()方法(參數就是Request對象)就能將這個網絡請求發出。當add方法調用后,Volley會自動創建一個緩存處理線程和一個網絡請求線程池,Volley會先判斷你發送網絡請求是否曾經存在於緩存中,若已經存在,那么緩存處理線程會對發出請求進行處理並返回結果(中間沒有任何網絡交互)。如果你發送的網絡請求在緩存沒有找到,那么這個請求會被放在網絡請求隊列中,網絡請求線程池中會逐個從網絡請求隊列中獲取請求內容,通過HTTP發生網絡請求事務,返回的結果由Volley返回給主線程。

Volley取消網絡請求操作

Volley庫可以在代碼中使用RequestQueue中的cancelAll()方法完成。比如,每個Request子類都有個setTag(Object obj)的方法,可以將每個tag設置為一類請求。比如你在一個Activity中的所有Request都用this(Activity的this就是該activity實例)作為setTag的參數,你可以隨時隨地調用RequestQueue的cancelAll(Object obj)方法,傳遞this作為obj的實參,這樣這個activity的所有網絡請求都被取消了。當然也可以傳遞任意的字符串類型的參數(最好有意義的字符串),代碼實例:

public static final String TAG = "MyTag";
StringRequest stringRequest; // Assume this exists.
RequestQueue mRequestQueue;  // Assume this exists.

// 給Request設置tag進行分來
stringRequest.setTag(TAG);

mRequestQueue.add(stringRequest);

取消網絡請求比較好的途徑是放在activity的onStop方法中(也可以是任何地方,這里是慣例),如下

@Override
protected void onStop () {
    super.onStop();
    if (mRequestQueue != null) {
        mRequestQueue.cancelAll(TAG);
    }
}

另外需要注意的是,Request的響應處理函數(Response.Listener和Response.ErrorListener,見上)此時不會被調用。

如何在Request中設置Htpp請求的Header, Body?

要想設置request中的http請求中的header, boday內容可以重載getHeader方法

StringRequest request = new StringRequest(Request.Method.POST, "www.yoururl.com", new Response.Listener<String>() {
    @Override
    public void onResponse(String s) {

    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError volleyError) {

    }
}){
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        HashMap<String, String> map = new HashMap<>();
        Map<String, String>  params = new HashMap<String, String>();
        params.put("User-Agent", "Nintendo Gameboy");
        params.put("Accept-Language", "fr");
        params.put("Authorization", "Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b");

        return params;
    }
};

對你有用的話,就點個贊吧, :)

2015-8-3編輯加入新內容

使用JsonOjectRequest來提交和獲取JSONObject格式的請求,不需要設置getParams和getBody(), 后台是Django restful API. 使用下列的代碼,灰常簡單.

    
//In MyFragment.java
HashMap<String, String> data = new HashMap<>();
data.put("username", "ppppppppp");
data.put("password", "a");
data.put("mobile_phone", "221212");

NetworkUtil.registerUser2(data);

//NetworkUtil.java
public static JSONObject registerUser2(final HashMap<String, String> data) { JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, formAPI(API_MYUSER), new JSONObject(data), new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject responseStr) { System.out.println(responseStr); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { LogUtils.d(TAG, volleyError.getMessage()); } }); AppController.getInstance().addToRequestQueue(jsonObjectRequest); return null; }

應用運行后,在Django后台打印的Log

[03/Aug/2015 23:23:43]"POST /myuser/ HTTP/1.1" 201 190
{u'username': u'ppppppppp', u'password': u'a', u'mobile_phone': u'221212'}
[03/Aug/2015 23:24:59]"POST /myuser/ HTTP/1.1" 201 192

這里有篇引用, http://stackoverflow.com/questions/19837820/volley-jsonobjectrequest-post-request-not-working

使用StringRequest做Post提交的時候,會想當然的將要傳入的數據放在getParams()函數中,但每次運行都是得到下面的錯誤, 意思是Bad Request, 應該是參數組成有誤:

02-12 21:42:54.774: E/Volley(19215): [46574] BasicNetwork.performRequest: Unexpected response code 400 for http://somename/token/

而用上面的JsonObjectRequest做提交,問題解決, 但這Volley提供的StringRequest方法,讓人想當然的會這么使用,在StackOverflow上有N多人碰到上面的錯誤,結果都切換成JsonObjectRequest.

另外使用JsonObjectRequest的一個典型的錯誤是使用下列代碼,

 RequestQueue queue = MyVolley.getRequestQueue();
        JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,SPHERE_URL,null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        System.out.println(response);
                        hideProgressDialog();
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                      hideProgressDialog();
                    }
                }) {
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                params.put("id","1");
                params.put("name", "myname");
                return params;
            };
        };
        queue.add(jsObjRequest);

這種做法無法正確提交請求!


免責聲明!

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



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