Android 关于网络操做通常都会介绍 HttpClient 以及 HttpConnection 这两个包。前者是 Apache 开源库,后者是 Android 自带 API。企业级应用,通常都会选择使用已经封装好的 http 框架。比较流行有 Volley、android-async-http、retrofit、okhttp、androidquery、AndroidAsync 等。他们各有特色,不一样的框架有不一样的效率,现在 Google 推出了官方的针对 Android 平台上的网络通讯库 Volley,能使网络通讯更快,更简单,更健壮,Volley 在提供了高性能网络通信功能的同时,对网络图片加载也提供了良好的支持,彻底能够知足简单 REST 客户端的需求。另外,但 Volley 扩展性很强,能够根据须要定制你本身的网络请求。css
Volley 是 Ficus Kirpatrick 在 Gooogle I/O 2013 发布的一个处理和缓存网络请求的库,能使网络通讯更快,更简单,更健壮。Volley 名称的由来 a burst or emission of many things or a large amount at once。在Gooogle I/O 2013 演讲上,其配图是一幅火弓箭。如图 1 所示。html
图 1 Gooogle I/O 2013 Volleyandroid
Volley 管理着处理和缓存网络请求,它节省了开发者的宝贵时间,一次又一次编写相同的网络调用/缓存代码。更少的重复代码,其中一个好处就是减小了 bug,这是全部开发者所指望的。git
所谓“一次又一次编写相同的网络调用/缓存代码”,就是 AsyncTask 以及你编写的经过 Web API 获取响应,并显示出来的逻辑/代码。咱们必须在 ProgressBar() 和 onPostExecute() 方法内照顾 ProgressBar/ProgressDialog 。虽然这不是一个艰巨的任务,但却很无聊,甚至感到厌倦,尽管我已经定义了 BaseTask 类来管理ProgressBar/ProgressDialog 的显示/取消,以及更多其它操做。如今,Volley 是替代 AsyncTask 的强大工具。github
Volley 适合小而快的数据传输,特别是针对如下两种状况:json
Volley 优点:缓存
- Volley 能够自动安排全部的网络请求。这意味着 Volley 会照顾你 APP 执行的从 Web 获取响应或图片全部的网络请求。
- Volley 提供透明的磁盘和内存缓存。
- Volley 提供强大的取消请求的 API。这意味着你能够取消一个单独的请求,或是你能够设置取消请求的块(能够为多个)或范围。
- Volley 提供强大的自定功能。
- Volley 提供调试和追踪工具。
Volley 使用了线程池来做为基础结构,主要分为主线程,cache 线程和 network 线程。主线程和 cache 线程都只有一个,而 NetworkDispatcher 线程能够有多个,这样能解决比并行问题。网络
图 2 Volley 架构架构
下载演示,将 Volley 库和演示项目导入到 eclipse 里,再将 Volley 库添加到演示项目。程序运行结果如图 3 所示,包含两个演示:网络获取 JSON 和 图片。app
图 3 左:程序主界面;中:点击“获取 JSON”;右:点击“获取 Image”
主程序 activity_main.xml 界面包含两个按钮,显示两个演示的 activity,核心代码以下所示:
public class MainActivity extends Activity {
Intent intent = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn_json).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, JsonDemo.class);
startActivity(intent);
}
});
findViewById(R.id.btn_img).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, ImgDemo.class);
startActivity(intent);
}
});
}
}
修改 AndroidManifest.xml 文件,添加受权 Android 访问网络的权限。
<uses-permission android:name="android.permission.INTERNET" />
经过 Volley 访问国家气象局提供的 JSON 接口,得到北京的天气情况。
activity_json.xml 页面文件包含一个 TextView 控件和一个 ProgreeBar 控件,略,核心代码以下所示:
package com.example.volleyexample;
import android.app.Activity;
import org.json.JSONObject;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class JsonDemo extends Activity {
private TextView txtDisplay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_json);
txtDisplay = (TextView) findViewById(R.id.txtDisplay);
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://www.weather.com.cn/data/sk/101010100.html";
JsonObjectRequest jsObjRequest = new JsonObjectRequest(
Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
// TODO Auto-generated method stub
txtDisplay.setText("Response => " + response.toString());
findViewById(R.id.progressBar1)
.setVisibility(View.GONE);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
queue.add(jsObjRequest);
}
}
activity_img.xml 页面文件包含两个控件:ImageView 和 NetworkImageView,其中,NetworkImageView 是 Volley 提供的控件,毕竟加载图片的使用频率很高,略,核心代码以下所示:
package com.example.volleyexample;
import org.json.JSONObject;
import com.android.volley.Request;
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.ImageLoader.ImageCache;
import com.android.volley.toolbox.ImageLoader.ImageListener;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.util.LruCache;
import android.widget.ImageView;
public class ImgDemo extends Activity {
String url = "http://images.cnblogs.com/cnblogs_com/liuning8023/588559/o_Android.jpg";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_img);
RequestQueue mRequestQueue = Volley.newRequestQueue(this);
final LruCache<String, Bitmap> mImageCache = new LruCache<String, Bitmap>(
20);
ImageCache imageCache = new ImageCache() {
@Override
public void putBitmap(String key, Bitmap value) {
mImageCache.put(key, value);
}
@Override
public Bitmap getBitmap(String key) {
return mImageCache.get(key);
}
};
ImageLoader mImageLoader = new ImageLoader(mRequestQueue, imageCache);
// ImageView
ImageView img = (ImageView) findViewById(R.id.imgView);
ImageListener listener = ImageLoader
.getImageListener(img, android.R.drawable.ic_menu_rotate,
android.R.drawable.ic_delete);
mImageLoader.get(url, listener);
// NetworkImageView
NetworkImageView netImgView = (NetworkImageView) findViewById(R.id.networkImgView);
netImgView.setTag("url");
netImgView.setImageUrl(url, mImageLoader);
}
}