Volley

(来源于慕课网JVR老师的讲课内容,本人整理总结)
还有网友的不错的总结,我写这篇文章只是出于梳理思路的目的。网友博客地址如下:
http://www.cnblogs.com/caobotao/p/5071658.html

Volley是网络通信库,适用于一些数据量不大,但需要频繁通信的网络操作。使用Volley进行网络开发可以提高开发效率和性能的稳定性。但是Volley不适用于文件的上传下载操作。
使用Volley
(下面这段话复制自上面网友的博客)
1.Volley的网络请求队列建立与取消队列请求

使用Volley需要建立一个全局的请求队列,这样我们就可以将一个请求加入到这个全局队列中,并可以管理整个APP的所有请求,包括取消一个或所有的请求。

2.Volley的Get和Post请求方式的使用

Volley的Get和Post请求方式其实是对Android原生Get和Post请求方式进行了二次封装,对效率等进行优化。在使用Get和Post请求方式之前,我们要确定所请求的数据返回什么对象,Volley自带了三种返回类型:

StringRequest:主要使用在对请求数据的返回类型不确定的情况下,StringRequest涵盖了JsonObjectRequest和JsonArrayRequest。

JsonObjectRequest:当确定请求数据的返回类型为JsonObject时使用。

JsonArrayRequest:当确定请求数据的返回类型为JsonArray时使用。

3.Volley与Activity生命周期的联动

简单来说就是Volley中的请求是与Activity的生命周期进行关联。这样可以在Android销毁时关闭Volley的请求,防止请求在后台运行造成内存溢出等情况发生。与Activity生命周期进行联动时需要设置Tag标签,因为取消请求需要在请求队列中通过Tag标签进行查找,在Activity的onStop中执行取消请求的操作。

代码示例:
首先将Volley.jar下载下来,放入libs目录下(eclipse)

/**
 * 创建一个全局的请求队列
 * @author Administrator
 *
 */
public class MyApplication extends Application {

    public static RequestQueue queues;

    @Override
    public void onCreate() {
        super.onCreate();
        queues = Volley.newRequestQueue(getApplicationContext());
    }

    public static RequestQueue getHttpQueues() {
        return queues;
    }
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.volleydemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="22" />

    <!-- 添加网络操作权限 -->
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- 注册自定义的Application:android:name=".MyApplication" -->
    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

1、使用Get方式返回StringRequest对象:
(注意包要导对)

public class MainActivity extends Activity {

    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.tv_text);
        volleyGetStringRequest();
    }

    /**
     * 使用GET方式请求StringRequest数据
     */
    private void volleyGetStringRequest() {
        // 可以百度聚合数据,里面有很多实用的工具。在个人中心申请数据就可以得到相应的KEY
        String url = "http://apis.juhe.cn/mobile/get?phone=你的11位手机号码&key=你申请的KEY";
        StringRequest request = new StringRequest(Method.GET, url, new Listener<String>() {

            @Override
            public void onResponse(String response) {
                Toast.makeText(MainActivity.this, response, Toast.LENGTH_LONG).show();
                mTextView.setText(response);
            }
        }, new ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
                mTextView.setText("请求失败!");
            }
        });
        // 设置请求的Tag标签,可以在全局请求队列中通过Tag标签进行请求的查找
        request.setTag("testGet");
        // 将请求加入全局队列中
        MyApplication.getHttpQueues().add(request);
    }
}

2、使用Get方式返回JsonObjectRequest对象:

/**
     * 使用GET方式请求JsonObjectRequest数据
     */
    private void volleyGetJsonObjectRequest() {
        String url = "http://apis.juhe.cn/mobile/get?phone=你的11位手机号码&key=你申请的KEY";
        JsonObjectRequest objectRequest = new JsonObjectRequest(Method.GET, url, null, new Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_LONG).show();
            }
        }, new ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
            }
        });
        objectRequest.setTag("testGet");
        MyApplication.getHttpQueues().add(objectRequest);
    }

3、使用Get方式返回JsonArrayRequest对象:

/**
     * 使用GET方式请求JsonArrayRequest数据
     */
    private void volleyGetJsonArrayRequest() {
        String url = "http://apis.juhe.cn/mobile/get?phone=你的11位手机号码&key=你申请的KEY";
        JsonArrayRequest arrayRequest = new JsonArrayRequest(url, new Listener<JSONArray>() {

            @Override
            public void onResponse(JSONArray response) {
                Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_LONG).show();
            }
        }, new ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
            }
        });
        arrayRequest.setTag("testGet");
        MyApplication.getHttpQueues().add(arrayRequest);
    }

4、使用Post方式返回StringRequest对象:

    /**
     * 使用POST方式请求StringRequest数据
     */
    private void volleyPostStringRequest() {
    // 查询邮编
        String url = "http://v.juhe.cn/postcode/query?";
        StringRequest request = new StringRequest(Method.POST, url, new Listener<String>() {

            @Override
            public void onResponse(String response) {
                Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_LONG).show();
            }
        }, new ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
            }
        })
        // 用户使用getParams()方法:用户在Volley中使用Post方式请求数据中参数的传递
        {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> hashMap = new HashMap<>();
                // 将请求参数名与参数值放入map中
                hashMap.put("postcode", "邮编号");
                hashMap.put("key", "你的KEY");
                return hashMap;
            }
        };
        request.setTag("testPost");
        MyApplication.getHttpQueues().add(request);
    }

5、使用Post方式返回StringRequest对象:

    /**
     * 使用POST方式请求JsonJsonObject数据
     */
    private void volleyPostJsonJsonObject() {
        String url = "http://v.juhe.cn/postcode/query?";
        HashMap<String, String> hashMap = new HashMap<>();
        // 将请求参数名与参数值放入map中
        hashMap.put("postcode", "719000");
        hashMap.put("key", "你的KEY");
        JSONObject jsonObject = new JSONObject(hashMap);

        JsonObjectRequest objectRequest = new JsonObjectRequest(Method.POST, url, jsonObject,
                new Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_LONG).show();
                    }
                }, new ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
                    }
                });
        objectRequest.setTag("testPost");
        MyApplication.getHttpQueues().add(objectRequest);
    }

6、使用Post方式返回JsonArrayRequest对象:
与5所讲述的是类似的,参考Get。

与Activity生命周期的联动

可以在Activity关闭时取消请求队列中的请求:

    @Override
    protected void onStop() {
        super.onStop();
        // 通过Tag标签取消请求队列中对应的全部请求
        MyApplication.getHttpQueues().cancelAll("testGet");
    }

自定义Volley(简单的二次回调封装):
优点:全局使用一个方式,可控、可自定义定制需求。方便、灵活。

/**
 * Volley请求成功和失败接口
 * 
 * @author Administrator
 *
 */
public abstract class VolleyInterface {

    public Context mContext;
    public static Listener<String> mListener;
    public static ErrorListener mErrorListener;

    public VolleyInterface(Context context, Listener<String> listener, ErrorListener errorListener) {
        this.mContext = context;
        VolleyInterface.mListener = listener;
        VolleyInterface.mErrorListener = errorListener;
    }

    public abstract void onMySuccess(String response);

    public abstract void onMyError(VolleyError error);

    public Listener<String> loadingListener() {
        mListener = new Listener<String>() {

            @Override
            public void onResponse(String response) {
                onMySuccess(response);
                // 提示弹出加载(全局)
            }
        };
        return mListener;
    }

    public ErrorListener errorListener() {
        mErrorListener = new ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                onMyError(error);
                // 提示请求失败(全局)
            }
        };
        return mErrorListener;
    }
}
/**
 * 自定义get和post请求
 * 
 * @author Administrator
 *
 */
public class VolleyRequest {

    public static StringRequest stringRequest;
    public static Context mContext;

    /**
     * get方式请求StringRequest对象
     * 
     * @param context
     *            上下文
     * @param url
     *            数据地址
     * @param tag
     *            标签
     * @param volleyInterface
     *            成功和失败接口
     */
    public static void RequestGet(Context context, String url, String tag, VolleyInterface volleyInterface) {
        MyApplication.getHttpQueues().cancelAll(tag);
        StringRequest stringRequest = new StringRequest(Method.GET, url, volleyInterface.loadingListener(),
                volleyInterface.errorListener());
        stringRequest.setTag(tag);
        MyApplication.getHttpQueues().add(stringRequest);
        MyApplication.getHttpQueues().start();
    }

    public static void RequestPost(Context context, String url, String tag, final Map<String, String> params,
            VolleyInterface volleyInterface) {
        MyApplication.getHttpQueues().cancelAll(tag);
        StringRequest stringRequest = new StringRequest(url, volleyInterface.loadingListener(),
                volleyInterface.errorListener()) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                // TODO Auto-generated method stub
                return params;
            }
        };
        stringRequest.setTag(tag);
        MyApplication.getHttpQueues().add(stringRequest);
        MyApplication.getHttpQueues().start();

    }
}

测试自定义MyVolley:

public class MyVolley extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        volleyGet();
    }

    private void volleyGet() {
        String url = "url地址";
        VolleyRequest.RequestGet(this, url, "testTag",
                new VolleyInterface(this, VolleyInterface.mListener, VolleyInterface.mErrorListener) {

                    @Override
                    public void onMySuccess(String response) {
                        Toast.makeText(MyVolley.this, response.toString(), Toast.LENGTH_LONG).show();
                    }

                    @Override
                    public void onMyError(VolleyError error) {
                        Toast.makeText(MyVolley.this, error.toString(), Toast.LENGTH_LONG).show();
                    }
                });
    }
}

成功运行。

使用ImageRequest获取网络图片:

/**
 * 使用ImageRequest获取网络图片
 * @author Administrator
 *
 */
public class MainActivity extends Activity {

    private ImageView mImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        mImageView = (ImageView) findViewById(R.id.img_web);

        String url = "http://img5q.duitang.com/uploads/item/201410/02/20141002194946_43Nda.jpeg";

        ImageRequest imageRequest = new ImageRequest(url, new Listener<Bitmap>() {

            @Override
            public void onResponse(Bitmap response) {
                mImageView.setImageBitmap(response);
            }
        }, 0, 0, Config.RGB_565, new ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                mImageView.setBackgroundResource(R.drawable.ic_launcher);
            }
        });
        MyApplication.getHttpQueues().add(imageRequest);
    }
}

使用ImageLoader缓存图片:

public class BitmapCache implements ImageCache {

    public LruCache<String, Bitmap> lruCache;
    // LruCache缓存对象的最大内存大小(10M)
    public int maxSize = 10 * 1024 * 1024;

    public BitmapCache() {
        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);
    }

}
public class ImageLoaderActivity extends Activity {

    private ImageView mImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        mImageView = (ImageView) findViewById(R.id.img_web);

        String url = "http://img5q.duitang.com/uploads/item/201410/02/20141002194946_43Nda.jpeg";

        // imageCache单独使用没有效果
        ImageLoader imageLoader = new ImageLoader(
                MyApplication.getHttpQueues(), 
                new BitmapCache());

        ImageListener imageListener = ImageLoader.getImageListener(
                mImageView,
                R.drawable.ic_launcher,
                R.drawable.ic_launcher);

        imageLoader.get(url, imageListener);
    }
}

使用Volley自带的NetworkImageView(简洁方便):

<com.android.volley.toolbox.NetworkImageView
        android:id="@+id/com_network"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp" />
/**
 * 使用NetworkImageView加载图片
 * @author Administrator
 *
 */
public class NetworkImageActivity extends Activity {

    private NetworkImageView mNetImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        mNetImageView = (NetworkImageView) findViewById(R.id.com_network);

        String url = "http://img5q.duitang.com/uploads/item/201410/02/20141002194946_43Nda.jpeg";

        ImageLoader imageLoader = new ImageLoader(
                MyApplication.getHttpQueues(), 
                new BitmapCache());
        // 只需设置默认图片、加载失败图片和图片地址
        mNetImageView.setDefaultImageResId(R.drawable.ic_launcher);
        mNetImageView.setErrorImageResId(R.drawable.load_fail);
        mNetImageView.setImageUrl(url, imageLoader);
    }
}

总体上Volley的用处分为这两个:
1、高效的Get/Post方式的数据请求交互;
2、网络图片的加载和缓存过程简单化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值