当前位置: 代码迷 >> Android >> android网络请求框架Volley(1)
  详细解决方案

android网络请求框架Volley(1)

热度:55   发布时间:2016-04-28 01:25:10.0
android网络请求框架Volley(一)

1 Volley的介绍

? ? Volley从服务器端请求字符串数据图片数据,和JSON格式数据。Volley可以写出标准化的模板代码,并让我们更加关注于我们的业务逻辑,这对于我们的App来说是非常重要的。

?

Volley的优势:

?

  • ?自动的调度网络请求
  • ?多并发的网络请求
  • ??可以缓存http请求
  • ?支持请求的优先级
  • ?支持取消请求的API,可以取消单个请求,可以设置取消请求的范围域。
  • ?代码标准化,使开发者更容易专注于我们的业务的逻辑处理
  • ?更容易给UI填充来自网络请求的数据
  • ?Volley可以是作为调试和跟踪的工具

? ? Volley非常不适合大的文件流操作,例如上传和下载。因为Volley会把所有的服务器端返回的数据在解析期间缓存进内存。大量的下载操作可以考虑用DownLoaderManager和异步加载来实现。

Volley库的地址如下:

git clone?https://android.googlesource.com/platform/frameworks/volley

?

2 Volley的工作原理

? ? ? 为了发送一个请求,你可以通过构造方法new出来一个Request,然后调用add()把请求添加进RequestQueue中,当调用add方法时,Volley会运行一个缓存处理线程和一个网络调度线程池.如果请求被缓存线程已经缓存的话,请求将不会放进请求队列,也就是说不会发出Http请求。而会直接复用请求,并将数据返回到主线程。如果缓存线程中没有缓存到请求的话,请求将会放进请求队列,网络请求成功后,?请求将会被缓存进cache,接着网络调度线程将处理该请求,并解析数据。
Volley的工作原理图如下:

3 使用volley请求数据

??? 3.1 利用StringRequest请求字符串数据

?? ?Volley提供了一个便利的方法Volley.newRequestQueue可以使用默认的设置创建一个RequestQueue,例如:

?

finalTextView mTextView =(TextView) findViewById(R.id.text);... // Instantiate the RequestQueue.RequestQueue queue =Volley.newRequestQueue(this);String url ="http://www.google.com"; // Request a string response from the provided URL.StringRequest stringRequest =newStringRequest(Request.Method.GET, url,newResponse.Listener<String>(){@Overridepublicvoid onResponse(String response){// Display the first 500 characters of the response string.mTextView.setText("Response is: "+ response.substring(0,500));}},newResponse.ErrorListener(){@Overridepublicvoid onErrorResponse(VolleyError error){mTextView.setText("That didn't work!");}});// Add the request to the RequestQueue.queue.add(stringRequest);
?

3.2 利用ImageRequest请求图片

publicclassMainActivityextendsActivity{privateImageView mImageView;@Overrideprotectedvoid onCreate(Bundle savedInstanceState){    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    mImageView =(ImageView) findViewById(R.id.iv_image); } publicvoid requestImage(){// Retrieves an image specified by the URL, displays it in the UI.   String url ="http://i.imgur.com/7spzG.png";   ImageRequest request =newImageRequest(url,   newResponse.Listener<Bitmap>(){@Overridepublicvoid onResponse(Bitmap bitmap){   Toast.makeText(MainActivity.this,"success",1).show();   mImageView.setImageBitmap(bitmap);}},0,0,null,newResponse.ErrorListener(){publicvoid onErrorResponse(VolleyError error){/*mImageView.setImageResource(R.drawable.image_load_error);*/}});    Volley.newRequestQueue(getApplicationContext()).add(request);} }
????

3.3 使用NetworkImageView结合imageLoader加载网络图片

<com.android.volley.toolbox.NetworkImageViewandroid:id="@+id/networkImageView"android:layout_width="150dp"android:layout_height="170dp"android:layout_centerHorizontal="true"/>
ImageLoader mImageLoader;ImageView mImageView;// The URL for the image that is being loaded.private static final String IMAGE_URL =    "http://developer.android.com/images/training/system-ui.png";...mImageView = (ImageView) findViewById(R.id.regularImageView); // Get the ImageLoader through your singleton class.  mImageLoader = MySingleton.getInstance(this).getImageLoader();  mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView,R.drawable.def_image, R.drawable.err_image));
?
TextView mTxtDisplay;ImageView mImageView;mTxtDisplay = (TextView) findViewById(R.id.txtDisplay);String url = "http://my-json-feed"; JsonObjectRequest jsObjRequest = new JsonObjectRequest        (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {     @Override    public void onResponse(JSONObject response) {        mTxtDisplay.setText("Response: " + response.toString());    }}, new Response.ErrorListener() {     @Override    public void onErrorResponse(VolleyError error) {        // TODO Auto-generated method stub     }}); // Access the RequestQueue through your singleton class.MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
?

?3.4 使用JsonObjectRequest请求json格式数据(个人感觉和StringRequest一样)

TextView mTxtDisplay;ImageView mImageView;mTxtDisplay = (TextView) findViewById(R.id.txtDisplay);String url = "http://my-json-feed"; JsonObjectRequest jsObjRequest = new JsonObjectRequest        (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {     @Override    public void onResponse(JSONObject response) {        mTxtDisplay.setText("Response: " + response.toString());    }}, new Response.ErrorListener() {     @Override    public void onErrorResponse(VolleyError error) {        // TODO Auto-generated method stub     }}); // Access the RequestQueue through your singleton class.MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);

4 如何取消请求

? ?Volley通过调用cancel()方法取消一个请求,并保证请求不会在Response中回调处理,你可以在activity中的onStop中取消所有你想取消的请求,最简单的方法就是给所有想取消的请求调用setTag(TAG)设置标记,然后放进请求队列,在Activity的onStop方法中调用cancelAll(TAG)方法取消请求。

?

代码如下:

?? 给请求设置TAG,并放进请求队列

?

public static final String TAG = "MyTag";StringRequest stringRequest; // Assume this exists.RequestQueue mRequestQueue;  // Assume this exists.// 给请求设置tagstringRequest.setTag(TAG);// 把请求放进请求队列mRequestQueue.add(stringRequest);

?? 在onstop方法中取消所有设置Tag的请求

?

?

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

?

?


注意:当取消请求的时候,onResponse和onErrorResponse方法将不会执行

?

5?如何新建一个RequestQueue

?5.1 RequestQueue的配置

? ? ? Volley.newRequestQueue??可以创建一个请求队列,但那只能使用Volley
的默认配置,下面来讲讲如何来创建自己的一个请求队列。每次去new一个请求队列是非常消耗内存的,我们可以利用单列模式来避免每次都去new一个请求队列。
?
RequestQueue mRequestQueue; // 配置缓存大小Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap // 设置网络请求方式(UrlConnection和HttpClient)Network network = new BasicNetwork(new HurlStack()); //初始化RequestQueuemRequestQueue = new RequestQueue(cache, network); // 开启RequestQueuemRequestQueue.start(); String url ="http://www.myurl.com"; // Formulate the request and handle the response.StringRequest stringRequest = new StringRequest(Request.Method.GET, url,        new Response.Listener<String>() {    @Override    public void onResponse(String response) {        // Do something with the response    }},    new Response.ErrorListener() {        @Override        public void onErrorResponse(VolleyError error) {            // Handle error    }}); // 把请求添加进请求队列mRequestQueue.add(stringRequest);
?5.2 RequestQueue中BasicNewWork(网络)的内部机制
?? ??查看volley源码可以知道:Volley一般联网的方式有HttpClient和HttpURLConnection,
如果API低于9的话可以调用HttpRULConnection请求网络,如果API高于9的话,会用HttpClient
请求网络,源码如下:

?

HttpStack stack;...// If the device is running a version >= Gingerbread...if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {    // ...use HttpURLConnection for stack.} else {    // ...use AndroidHttpClient for stack.}Network network = new BasicNetwork(stack);  

?

?5.3 ?使用requestQueue的注意事项

?

  • 如果你的项目要进行频繁的网路请求,你可以在application的onCreate方法中创建一个RequestQueue,google官方文档强烈建议我们把RequestQueue设计成单列模式。
  • 但是要注意,在RequestQueue中的Context对象为applicationContext,而不是Activity对应的context对象,可以避免在activity中每次都去消费使用activity中的context对象。
下面是使用单列设计模式创建的一个请求队列

?

private static MySingleton mInstance;    private RequestQueue mRequestQueue;    private static Context mCtx;     public static synchronized MySingleton getInstance(Context context) {        if (mInstance == null) {            mInstance = new MySingleton(context);        }        return mInstance;    }     public RequestQueue getRequestQueue() {        if (mRequestQueue == null) {            // getApplicationContext() is key, it keeps you from leaking the            // Activity or BroadcastReceiver if someone passes one in.            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());        }        return mRequestQueue;    }     public <T> void addToRequestQueue(Request<T> req) {        getRequestQueue().add(req);    }     public ImageLoader getImageLoader() {        return mImageLoader;    }}
?

?

?

?

  相关解决方案