博客参考自《第一行代码》作者
博客地址Volley使用总结
Volley简介
我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据。Android系统中主要提供了两种方式来进行HTTP通信,HttpURLConnection和HttpClient,几乎在任何项目的代码中我们都能看到这两个类的身影,使用率非常高。
不过HttpURLConnection和HttpClient的用法还是稍微有些复杂的,如果不进行适当封装的话,很容易就会写出不少重复代码。于是乎,一些Android网络通信框架也就应运而生,比如说AsyncHttpClient,它把HTTP所有的通信细节全部封装在了内部,我们只需要简单调用几行代码就可以完成通信操作了。再比如Universal-Image-Loader,它使得在界面上显示网络图片的操作变得极度简单,开发者不用关心如何从网络上获取图片,也不用关心开启线程、回收图片资源等细节,Universal-Image-Loader已经把一切都做好了。
Android开发团队也是意识到了有必要将HTTP的通信操作再进行简单化,于是在2013年Google I/O大会上推出了一个新的网络通信框架——Volley。Volley可是说是把AsyncHttpClient和Universal-Image-Loader的优点集于了一身,既可以像AsyncHttpClient一样非常简单地进行HTTP通信,也可以像Universal-Image-Loader一样轻松加载网络上的图片。除了简单易用之外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕
。
Volley的使用
package own.w.nl.com.oschina;
import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONObject;
import util.MyImageCache;
public class MainActivity extends AppCompatActivity {
private String url="http://192.168.191.1:8008/SendJson/servlet/JsonServlet01";
private String imageUrl="http://192.168.191.1:8008/SendJson/android.png";
private static final String TAG="MainActivity";
private ImageView image;
private RequestQueue requestQueue=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取请求队列,缓存所有的HTTP请求
requestQueue= Volley.newRequestQueue(MainActivity.this);
image=(ImageView)findViewById(R.id.java);
}
/**
* Get请求
*
前面已经说过,Volley的用法非常简单,那么我们就从最基本的HTTP通信开始学习吧,即发起一条HTTP请求,然后接收HTTP响应。首先需要获取到一个RequestQueue对象,可以调用如下方法获取到
RequestQueue mQueue = Volley.newRequestQueue(context);
注意这里拿到的RequestQueue是一个请求队列对象,它可以缓存所有的HTTP请求,然后按照一定的算法并发地发出这些请求。RequestQueue内部的设计就是非常合适高并发的,因此我们不必为每一次HTTP请求都创建一个RequestQueue对象,这是非常浪费资源的,基本上在每一个需要和网络交互的Activity中创建一个RequestQueue对象就足够了。
接下来为了要发出一条HTTP请求,我们还需要创建一个StringRequest对象。
可以看到,这里new出了一个StringRequest对象,StringRequest的构造函数需要传入三个参数,第一个参数就是目标服务器的URL地址,第二个参数是服务器响应成功的回调,第三个参数是服务器响应失败的回调。其中,目标服务器地址我们填写的是百度的首页,然后在响应成功的回调里打印出服务器返回的内容,在响应失败的回调里打印出失败的详细信息。
最后,将这个StringRequest对象添加到RequestQueue里面就可以了。
###**总结步骤
1. 创建一个RequestQueue对象。
2. 创建一个StringRequest对象。
3. 将StringRequest对象添加到RequestQueue里面。**
*/
public void requestGet(View view){
StringRequest stringRequest=new StringRequest(url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.e(TAG,response);
Toast.makeText(getApplicationContext(),"成功"+response,Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG,error.toString());
Toast.makeText(getApplicationContext(),""+error.toString(),Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(stringRequest);
}
/**
* POST请求
*/
public void requestPost(View view){
}
/**
* 直接请求json数据
学完了最基本的StringRequest的用法,我们再来进阶学习一下JsonRequest的用法。类似于StringRequest,JsonRequest也是继承自Request类的,不过由于JsonRequest是一个抽象类,因此我们无法直接创建它的实例,那么只能从它的子类入手了。JsonRequest有两个直接的子类,JsonObjectRequest和JsonArrayRequest,从名字上你应该能就看出它们的区别了吧?一个是用于请求一段JSON数据的,一个是用于请求一段JSON数组的。
可以看到,这里我们填写URL,响应的数据就是以JSON格式返回的,然后我们在onResponse()方法中将返回的数据打印出来。
最后再将这个JsonObjectRequest对象添加到RequestQueue里就可以了
至于它们的用法也基本上没有什么特殊之处,先new出一个JsonObjectRequest对象
*/
public void getJson(View view){
// String url="http://m.weather.com.cn/data/101010100.html";
JsonObjectRequest jsonObjectRequest=new JsonObjectRequest(url, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Toast.makeText(getApplicationContext(),""+response.toString(),Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),""+error.toString(),Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(jsonObjectRequest);
}
public void getImage(View view){
ImageRequest imageRequest=new ImageRequest(imageUrl, new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
image.setImageBitmap(response);
image.setVisibility(View.VISIBLE);
}
}, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(imageRequest);
}
public void getPicByImageLoader(View view){
//方法一
// ImageLoader imageLoader=new ImageLoader(requestQueue, new ImageLoader.ImageCache() {
// @Override
// public Bitmap getBitmap(String url) {
// Log.e(TAG+"getBitmap",url+"");
// return null;
// }
//
// @Override
// public void putBitmap(String url, Bitmap bitmap) {
// Log.e(TAG+"putBitmap",url+"");
// }
// });
//方法二 优化
ImageLoader imageLoader=new ImageLoader(requestQueue,new MyImageCache());
ImageLoader.ImageListener listener=ImageLoader.getImageListener(image,R.drawable.sucess,R.drawable.error);
// imageLoader.get(imageUrl,listener);
imageLoader.get(imageUrl,listener,120,120);
}
}
package util;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import com.android.volley.toolbox.ImageLoader;
/**
* Created by ASUS on 2016/9/27.
*/
public class MyImageCache implements ImageLoader.ImageCache {
private LruCache<String,Bitmap> lruCache;
public MyImageCache() {
//缓存图片的大小设置为10M
int maxSize=10*1024*1024;
lruCache=new LruCache<String, Bitmap>(maxSize){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return lruCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
lruCache.put(url, bitmap);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="requestGet"
android:text="Get请求数据" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="requestPost"
android:text="POst请求数据" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="getJson"
android:text="Get请求json数据" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="getImage"
android:text="ImageRequest 加载图片" />
<ImageView
android:id="@+id/java"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="getPicByImageLoader"
android:text="ImageLoader 加载图片" />
</LinearLayout>
</ScrollView>
</LinearLayout>