在Android开发中,网络请求是最重要的模块之一,Android中大部分网络请求使用的是HTTP连接,包括原生的HttpClient和HttpUrlConnection两种访问网络方式。需要注意的是,HttpClient方式在Android6.0以后,很多类已经不支持了。
目前主流的开源网络框架,主要有OkHttp,Volley,Retrofit三种,我本人在短暂的开发经历中基本也只接触过这几个,在此简单分析这三个框架,仅作为本人记录。
Volley框架
Volley框架是由Google在2013年发布的较为轻量级的网络框架,主要适用于处理请求次数较多,量级较小的网络请求。
一、Volley使用方式
Volley的使用方式十分简单,主要分为以下几步:
Step1: 引入Volley(Android Studio)
方法一:在项目的build.gradle 添加依赖
implementation 'com.mcxiaoke.volley:library:1.0.+'
方法二:引入volley.jar包
方法三:通过git下载volley包,之后添加为项目的module,并为主工程添加依赖
需要注意的是,如果Volley返回Object,需要对其进行解析,转换为Gson对象,那么还需要引入Gson依赖
implementation 'com.google.code.gson:gson:2.8.2'
注:引入的版本根据sdk版本而定
Step2: 创建请求队列实例
requestQueue = Volley.newRequestQueue(context);
一般而言,请求队列不需要每次进行网络请求时创建,通常一个Activity创建一个,或者对于较少请求的轻量级的应用,也可以一个应用只创建一个请求队列,主要视请求的多少而定。
Step3: 创建请求Request
Volley本身已封装好几种常用的Request,包括StringRequest,JsonRequest,JsonObjectRequest,JsonArrayRequest
值得一提的是,Volley封装了ImageLoader和ImageRequest,可以方便地支持图片的获取和加载,不需要额外自己添加图片的加载
以StringRequest为例,创建Request的代码也十分简单:
StringRequest stringRequest = new StringRequest(url, new Listener<String>() {
@Override
public void onResponse(String response) {
Log.e("xxxx", "onStringResponse: " + response);
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("xxxx", "onStringErrorResponse: " + error);
}
});
Step4: 将请求加入请求队列
requestQueue.add(stringRequest);
经过以上几个步骤,就可以实现网络请求,成功和失败结果均返回。
二、Volley源码分析
Volley作为一个轻量级的网络框架,源码实际上并不复杂,接下来将针对其主要的代码进行分析。
1. Volley.java 的主要代码分析
图中截出的就是我们在使用Volley时的第一步创建请求队列的代码,事实上Volley文件中也只有这一个重要的函数,主要步骤如下:
public static RequestQueue newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes) {
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
String userAgent = "volley/0";
try {
String packageName = context.getPackageName();
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
userAgent = packageName + "/" + info.versionCode;
} catch (NameNotFoundException e) {
}
if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
stack = new HurlStack();
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
Network network = new BasicNetwork(stack);
RequestQueue queue;
if (maxDiskCacheBytes <= -1)
{
// No maximum size specified
queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
}
else
{
// Disk cache size specified
queue = new RequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network);
}
queue.start();
return queue;
}
- 创建了一个用于存储Volley缓存的文件,使用的是默认的缓存路径,然后获取包名、包的信息以及用户信息等
- 根据sdk版本,sdk版本大于等于9的,即Android系统2.3版本以上,创建HurlStack,9以下创建HttpClientStack
- 创建了请求队列,maxDiskCacheBytes指的是缓存的最大容量,在创建队列时如果定义了该参数,则按指定的容量,否则缓存容量为按照默认的-1
- RequestQueue.start()
2. RequestQueue的代码分析部分
RequestQueue最重要的是add和start两个函数。
start函数:
/**
* Starts the dispatchers in this queue.
*/
public void start() {
stop(); // Make sure any currently running dispatchers are stopped.
// Create the cache dispatcher and start it.
mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
mCacheDispatcher.start();
// Create network dispatchers (and corresponding threads) up to the pool size.
for (int i = 0; i < mDispatchers.length; i++) {
NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,
mCache, mDelivery);
mDispatchers[i] = networkDispatcher;
networkDispatcher.start();
}
}
可以看到主要的步骤是创建并启动了两种分发器,其中mNetworkDispatchers包含多个NetworkDispatcher,数量默认为4。
add函数的主要代码如图所示: