Android HTTP框架Volley详解

From:http://www.androidhive.info/2014/05/android-working-with-volley-library-1/

Android volley is a networking library was introduced to make networking calls much easier, faster without writing tons of code. By default all the volley network calls works asynchronously, so we don’t have to worry about using asynctask anymore.

Volley comes with lot of features. Some of them are

1. Request queuing and prioritization
2. Effective request cache and memory management
3. Extensibility and customization of the library to our needs
4. Cancelling the requests

Before getting into this tutorial, I suggested you to view the below presentation by Ficus Kirkpatrick at Google I/O to get an overview of volley.

1. Creating New Project

1. In Android Studio, create a new project by navigating to File ⇒ New Project and fill all the required details. When it prompts to select a default activity, select Blank Activity and proceed.

2. Create two packages named app and utils to keep the project organized.

3. Open build.gradle and add volley support by adding
compile ‘com.mcxiaoke.volley:library-aar:1.0.0’ under dependencies section.

dependencies {
     compile fileTree(dir: 'libs' , include: [ '*.jar' ])
     compile 'com.android.support:appcompat-v7:22.2.0'
     compile 'com.android.volley:volley:1.0.0'
}

1.1 Creating Volley Singleton Class

The best way to maintain volley core objects and request queue is, making them global by creating a singleton class which extends Application object.

4. Under utils package, create a class named LruBitmapCache.java and paste the below code. This class is required to handle image cache.

LruBitmapCache.java
package info.androidhive.volleyexamples.volley.utils;
 
import com.android.volley.toolbox.ImageLoader.ImageCache;
 
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
 
public class LruBitmapCache extends LruCache<String, Bitmap> implements
         ImageCache {
     public static int getDefaultLruCacheSize() {
         final int maxMemory = ( int ) (Runtime.getRuntime().maxMemory() / 1024 );
         final int cacheSize = maxMemory / 8 ;
 
         return cacheSize;
     }
 
     public LruBitmapCache() {
         this (getDefaultLruCacheSize());
     }
 
     public LruBitmapCache( int sizeInKiloBytes) {
         super (sizeInKiloBytes);
     }
 
     @Override
     protected int sizeOf(String key, Bitmap value) {
         return value.getRowBytes() * value.getHeight() / 1024 ;
     }
 
     @Override
     public Bitmap getBitmap(String url) {
         return get(url);
     }
 
     @Override
     public void putBitmap(String url, Bitmap bitmap) {
         put(url, bitmap);
     }
}

5. Under app package, create a class name AppController.java and extend the class from Application and add the following code.

AppController.java
package info.androidhive.volleyexamples.app;
 
import info.androidhive.volleyexamples.volley.utils.LruBitmapCache;
import android.app.Application;
import android.text.TextUtils;
 
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
 
public class AppController extends Application {
 
     public static final String TAG = AppController. class
             .getSimpleName();
 
     private RequestQueue mRequestQueue;
     private ImageLoader mImageLoader;
 
     private static AppController mInstance;
 
     @Override
     public void onCreate() {
         super .onCreate();
         mInstance = this ;
     }
 
     public static synchronized AppController getInstance() {
         return mInstance;
     }
 
     public RequestQueue getRequestQueue() {
         if (mRequestQueue == null ) {
             mRequestQueue = Volley.newRequestQueue(getApplicationContext());
         }
 
         return mRequestQueue;
     }
 
     public ImageLoader getImageLoader() {
         getRequestQueue();
         if (mImageLoader == null ) {
             mImageLoader = new ImageLoader( this .mRequestQueue,
                     new LruBitmapCache());
         }
         return this .mImageLoader;
     }
 
     public <T> void addToRequestQueue(Request<T> req, String tag) {
         // set the default tag if tag is empty
         req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
         getRequestQueue().add(req);
     }
 
     public <T> void addToRequestQueue(Request<T> req) {
         req.setTag(TAG);
         getRequestQueue().add(req);
     }
 
     public void cancelPendingRequests(Object tag) {
         if (mRequestQueue != null ) {
             mRequestQueue.cancelAll(tag);
         }
     }
}

6. Now open AndroidManifest.xml and add this singleton class in <application> tag using android:name property to execute the class automatically whenever app launches. Also add INTERNET permission as we are going to make network calls.

AndroidManifest.xml
<? xml version = "1.0" encoding = "utf-8" ?>
< manifest xmlns:android = "http://schemas.android.com/apk/res/android"
     package = "info.androidhive.volleyexamples"
     android:versionCode = "1"
     android:versionName = "1.0" >
 
     < uses-sdk
         android:minSdkVersion = "8"
         android:targetSdkVersion = "19" />
 
     < uses-permission android:name = "android.permission.INTERNET" />
 
     < application
         android:name = "info.androidhive.volleyexamples.app.AppController"
         android:allowBackup = "true"
         android:icon = "@drawable/ic_launcher"
         android:label = "@string/app_name"
         android:theme = "@style/AppTheme" >
         <!-- all activities and other stuff -->
     </ application >
 
</ manifest >

Now the primary setup required for volley is done. Let’s move on to individual options those volley provides to make the http requests.

2. Making JSON request

Volley provides an easy to make json requests. If you are expecting json object in the response, you should use JsonObjectRequest class or if the response is json array, JsonArrayRequest class should be used.

2.1 Making json object request
Following code will make a json object request where the json response will start with object notation ‘{

// Tag used to cancel the request
String tag_json_obj = "json_obj_req" ;
 
         
ProgressDialog pDialog = new ProgressDialog( this );
pDialog.setMessage( "Loading..." );
pDialog.show();    
         
         JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.GET,
                 url, null ,
                 new Response.Listener<JSONObject>() {
 
                     @Override
                     public void onResponse(JSONObject response) {
                         Log.d(TAG, response.toString());
                         pDialog.hide();
                     }
                 }, new Response.ErrorListener() {
 
                     @Override
                     public void onErrorResponse(VolleyError error) {
                         VolleyLog.d(TAG, "Error: " + error.getMessage());
                         // hide the progress dialog
                         pDialog.hide();
                     }
                 });
 
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);

2.2 Making json array request
Following will make json array request where the json response starts with array notation ‘[

// Tag used to cancel the request
String tag_json_arry = "json_array_req" ;
 
         
ProgressDialog pDialog = new ProgressDialog( this );
pDialog.setMessage( "Loading..." );
pDialog.show();    
         
JsonArrayRequest req = new JsonArrayRequest(url,
                 new Response.Listener<JSONArray>() {
                     @Override
                     public void onResponse(JSONArray response) {
                         Log.d(TAG, response.toString());       
                         pDialog.hide();            
                     }
                 }, new Response.ErrorListener() {
                     @Override
                     public void onErrorResponse(VolleyError error) {
                         VolleyLog.d(TAG, "Error: " + error.getMessage());
                         pDialog.hide();
                     }
                 });
 
// Adding request to request queue
AppController.getInstance().addToRequestQueue(req, tag_json_arry);

3. Making String request

StringRequest class will be used to fetch any kind of string data. The response can be json, xml, html or plain text.

// Tag used to cancel the request
String  tag_string_req = "string_req" ;
 
         
ProgressDialog pDialog = new ProgressDialog( this );
pDialog.setMessage( "Loading..." );
pDialog.show();    
         
StringRequest strReq = new StringRequest(Method.GET,
                 url, new Response.Listener<String>() {
 
                     @Override
                     public void onResponse(String response) {
                         Log.d(TAG, response.toString());
                         pDialog.hide();
 
                     }
                 }, new Response.ErrorListener() {
 
                     @Override
                     public void onErrorResponse(VolleyError error) {
                         VolleyLog.d(TAG, "Error: " + error.getMessage());
                         pDialog.hide();
                     }
                 });
 
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);

4. Adding post parameters

It is obvious that sometimes we need to submit request parameters while hitting the url. To do that we have to override getParams() method which should return list of parameters to be send in a key value format.

If you observe below example, I am submitting name, email and password as request parameters.

// Tag used to cancel the request
String tag_json_obj = "json_obj_req" ;
 
         
ProgressDialog pDialog = new ProgressDialog( this );
pDialog.setMessage( "Loading..." );
pDialog.show();    
         
         JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.POST,
                 url, null ,
                 new Response.Listener<JSONObject>() {
 
                     @Override
                     public void onResponse(JSONObject response) {
                         Log.d(TAG, response.toString());
                         pDialog.hide();
                     }
                 }, new Response.ErrorListener() {
 
                     @Override
                     public void onErrorResponse(VolleyError error) {
                         VolleyLog.d(TAG, "Error: " + error.getMessage());
                         pDialog.hide();
                     }
                 }) {
 
             @Override
             protected Map<String, String> getParams() {
                 Map<String, String> params = new HashMap<String, String>();
                 params.put( "name" , "Androidhive" );
                 params.put( "email" , "abc@androidhive.info" );
                 params.put( "password" , "password123" );
 
                 return params;
             }
 
         };
 
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);

5. Adding request headers

Just like adding request parameters, to send request headers, we have to override getHeaders(). In below example I am sending Content-Type and apiKey in request headers.

// Tag used to cancel the request
String tag_json_obj = "json_obj_req" ;
 
         
ProgressDialog pDialog = new ProgressDialog( this );
pDialog.setMessage( "Loading..." );
pDialog.show();    
         
         JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.POST,
                 url, null ,
                 new Response.Listener<JSONObject>() {
 
                     @Override
                     public void onResponse(JSONObject response) {
                         Log.d(TAG, response.toString());
                         pDialog.hide();
                     }
                 }, new Response.ErrorListener() {
 
                     @Override
                     public void onErrorResponse(VolleyError error) {
                         VolleyLog.d(TAG, "Error: " + error.getMessage());
                         pDialog.hide();
                     }
                 }) {
 
             /**
              * Passing some request headers
              * */
             @Override
             public Map<String, String> getHeaders() throws AuthFailureError {
                 HashMap<String, String> headers = new HashMap<String, String>();
                 headers.put( "Content-Type" , "application/json" );
                 headers.put( "apiKey" , "xxxxxxxxxxxxxxx" );
                 return headers;
             }
 
         };
 
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);

6. Making Image request

Volley introduced custom image view element called NetworkImageView to display the images from an URL. Previously downloading images and maintaining caches is a tough job. Now using volley this can be done with very few lines of code.

6.1 Loading image in NetworkImageView
Following will load an image from an URL into NetworkImageView.

ImageLoader imageLoader = AppController.getInstance().getImageLoader();
 
// If you are using NetworkImageView
imgNetWorkView.setImageUrl(Const.URL_IMAGE, imageLoader);

6.2 Loading image in ImageView
If you want to load image into ImageView instead of NetworkImageView, you can do that too as mentioned below. Here we will have success and error callbacks, you have to take appropriate action depending on the need. Below in onResponse() method using response.getBitmap() I am loading bitmap into an ImageView.

ImageLoader imageLoader = AppController.getInstance().getImageLoader();
 
// If you are using normal ImageView
imageLoader.get(Const.URL_IMAGE, new ImageListener() {
 
     @Override
     public void onErrorResponse(VolleyError error) {
         Log.e(TAG, "Image Load Error: " + error.getMessage());
     }
 
     @Override
     public void onResponse(ImageContainer response, boolean arg1) {
         if (response.getBitmap() != null ) {
             // load image into imageview
             imageView.setImageBitmap(response.getBitmap());
         }
     }
});

6.3 Defining placeholder image and error image
Here is another way of displaying image into ImageView with the option of placeholder for loader and error. The loader placeholder will be displayed until the image gets downloaded. If the image fails to download, the error placeholder will be displayed.

// Loading image with placeholder and error image
imageLoader.get(Const.URL_IMAGE, ImageLoader.getImageListener(
                 imageView, R.drawable.ico_loading, R.drawable.ico_error));

7. Handling the volley Cache

Volley comes with powerful cache mechanism to maintain request cache. This saves lot of internet bandwidth and reduces user waiting time. Following are few example of using volley cache methods.

7.1 Loading request from cache
Like below you can check for a cached response of an URL before making a network call.

Cache cache = AppController.getInstance().getRequestQueue().getCache();
Entry entry = cache.get(url);
if (entry != null ){
     try {
         String data = new String(entry.data, "UTF-8" );
         // handle data, like converting it to xml, json, bitmap etc.,
     } catch (UnsupportedEncodingException e) {     
         e.printStackTrace();
         }
     }
} else {
     // Cached response doesn't exists. Make network call here
}

7.2 Invalidate cache
Invalidate means we are invalidating the cached data instead of deleting it. Volley will still uses the cached object until the new data received from server. Once it receives the response from the server it will override the older cached response.

AppController.getInstance().getRequestQueue().getCache().invalidate(url, true );

7.3 Turning off cache
If you want disable the cache for a particular url, you can use setShouldCache() method as below.

// String request
StringRequest stringReq = new StringRequest(....);
 
// disable cache
stringReq.setShouldCache( false );

7.4 Deleting cache for particular URL
Use remove() to delete cache of an URL.

AppController.getInstance().getRequestQueue().getCache().remove(url);

7.5 Deleting all the cache
Followoing will delete the cache for all the URLs.

AppController.getInstance().getRequestQueue().getCache().clear(url);

8. Cancelling requests

If you notice addToRequestQueue(request, tag) method, it accepts two parameters. One is request object and other is request tag. This tag will be used to identify the request while cancelling it. If the tag is same for multiple requests, all the requests will be cancelled. cancellAll() method is used to cancel any request.

8.1 Cancel single request
Following will cancel all the request with the tag named “feed_request”

String tag_json_arry = "json_req" ;
ApplicationController.getInstance().getRequestQueue().cancelAll( "feed_request" );

8.2 Cancel all requests
If you don’t pass any tag to cancelAll() method, it will cancel the request in request queue.

ApplicationController.getInstance().getRequestQueue().cancelAll();

9. Request prioritization

If you are making multiple request at the same time, you can prioritize the requests those you want be executed first. The priory can be Normal, Low, Immediate and High.

private Priority priority = Priority.HIGH;
 
StringRequest strReq = new StringRequest(Method.GET,
                 Const.URL_STRING_REQ, new Response.Listener<String>() {
 
                     @Override
                     public void onResponse(String response) {
                         Log.d(TAG, response.toString());
                         msgResponse.setText(response.toString());
                         hideProgressDialog();
 
                     }
                 }, new Response.ErrorListener() {
 
                     @Override
                     public void onErrorResponse(VolleyError error) {
                         VolleyLog.d(TAG, "Error: " + error.getMessage());
                         hideProgressDialog();
                     }
                 }) {
             @Override
             public Priority getPriority() {
                 return priority;
             }
 
         };

Missing! Making XML request

As of now volley doesn’t provided any native classes to make XML requests, but this can be achieved by building a custom xml wrapper class by utilizing volley’s customization capabilities. The part of writing xml parser using volley will be covered in upcoming tutorial.

I have given a sample project covering the scenarios explained in this tutorial. Download it and let’s discuss the queries if you have any in the comments section :)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值