在《Android 项目实践(一)——开发流程 》博客中,简单的说明了项目开发的大体流程。博主的此次项目实践是通过模仿别人的应用,而非自主开发,所以在前期的应用需求设计就不在分析设计。直接进入第二个阶段架构设计。本节来讲解架构设计的网络连接。
一、为什么要封装网络连接?
有人可能会有这样的疑虑,在Android中包含多种网络连接方式HttpURLConnection,URLConnection,HttpClient,Volley,XUtils等等,我们随意拿一种使用即可,为什么还要给应用单独做一种网络连接。原因:正是由于Android开发网络连接方式多样,以至于我们在以后对应用的升级和维护中可能会更改应用连接网络的方式,当我们对网络的连接方式进行更改时,可能就会需要改动大量的代码,这就有可额会导致整个项目出错。但是,如果我们在应用中封装自己的网络连接方式,项目中所有的网络连接都使用我们自己的网络连接,当我们对连接方式进行改变时,只需要改动封装的内容即可。
二、网络连接方式
《Android 网络连接——URLConnection 》
《Android 网络连接——HttpURLConnection 》
《Android 网络连接——HttpClient 》
《Android 网络连接——Volley 》
《Android 网络连接——xUtils网络框架 》
三、网络连接设计
前面了解了为什么要对网络连接进行封装,接下来我们就通过代码来实现,这里我们使用Volley连接网络(建议网络连接不要使用HttpURLConnection,HttpClient,因为这两种网络连接不自带线程,在使用是需要创建线程调用。),整体代码:
/**
* Created by Administrator on 2015/10/9.
* 所有的网络连接使用此类,此类的作用就是异步调用,统一网络连接
*/
public class InternetConnection {
//将网络连接单例
private static InternetConnection mConnection;
private InternetConnection() {
}
public static synchronized InternetConnection getInstance() {
if (mConnection == null) {
mConnection = new InternetConnection();
}
return mConnection;
}
/**
* 监听网络连接上的接口
*/
public interface OnConnectionListerner {
/**
* 网络连接的状态的。
* @param connection 判断网络是否连接,连接返回true,未连接返回false
* @param type 如果连接网络,返回网络的连接类型。
*/
void isConnection(boolean connection, String type);
/**
* 连接网络成功回调的方法。
* @param response 返回网络的返回值
*/
void onSuccessConnection(String response);
/**
* 网络连接错误
* @param response 返回“网络连接错误”字符串
* @param statusCode 返回连接的错误码
*/
void onFailConnection(String response, int statusCode);
}
/**
* 提交HashMap数据的网络连接
* @param url 网络连接的URL网址
* @param map 提交的数据
* @param connectionListerner 网络连接的监听对象, 获得网络的连接状态
*/
public void addRequest(String url, final HashMap<String, String> map, final OnConnectionListerner connectionListerner) {
//获取网络的状态
if (!NetWorkUtils.isConnection()) {
connectionListerner.isConnection(false, null);
} else {
connectionListerner.isConnection(true, NetWorkUtils.getConnectionType());
}
//创建请求
StringRequest request = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
connectionListerner.onSuccessConnection(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if(error.networkResponse==null){
connectionListerner.onFailConnection("网络连接失败", 404);
}else {
connectionListerner.onFailConnection("网络连接失败", error.networkResponse.statusCode);
}
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return map;
}
};
//创建请求队列并将请求添加到请求队列中
VolleySingleton.getInstance(BaseApplication.getContext()).addToRequestQueue(request);
}
}
1、InternetConnection网络连接单例模式
将网络连接实现单例模式。
单例模式实现的步骤:1. 创建私有化的对象,并实现静态修饰。2.私有化构造器,使其不能够创建对象。3.对外提供共有的方法获取该类对象。
//将网络连接单例
private static InternetConnection mConnection;
private InternetConnection() {
}
public static synchronized InternetConnection getInstance() {
if (mConnection == null) {
mConnection = new InternetConnection();
}
return mConnection;
}
2、创建监听内部接口
创建监听的内部接口,当在使用请求网络连接方法连接网络时传入此监听器接口的对象,从而实现对网络是否连接,连接成功或失败的监听。
/**
* 监听网络连接上的接口
*/
public interface OnConnectionListerner {
/**
* 网络连接的状态的。
* @param connection 判断网络是否连接,连接返回true,未连接返回false
* @param type 如果连接网络,返回网络的连接类型。
*/
void isConnection(boolean connection, String type);
/**
* 连接网络成功回调的方法。
* @param response 返回网络的返回值
*/
void onSuccessConnection(String response);
/**
* 网络连接错误
* @param response 返回“网络连接错误”字符串
* @param statusCode 返回连接的错误码
*/
void onFailConnection(String response, int statusCode);
}
3、网络请求方法
设置网络的请求方法,这里使用Volley连接网络。该方法有是三个参数:url地址,提交的数据,监听器对象。
/**
* 提交HashMap数据的网络连接
* @param url 网络连接的URL网址
* @param map 提交的数据
* @param connectionListerner 网络连接的监听对象, 获得网络的连接状态
*/
public void addRequest(String url, final HashMap<String, String> map, final OnConnectionListerner connectionListerner) {
//获取网络的状态
if (!NetWorkUtils.isConnection()) {
connectionListerner.isConnection(false, null);
} else {
connectionListerner.isConnection(true, NetWorkUtils.getConnectionType());
}
//创建请求
StringRequest request = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
connectionListerner.onSuccessConnection(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if(error.networkResponse==null){
connectionListerner.onFailConnection("网络连接失败", 404);
}else {
connectionListerner.onFailConnection("网络连接失败", error.networkResponse.statusCode);
}
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return map;
}
};
//创建请求队列并将请求添加到请求队列中
VolleySingleton.getInstance(BaseApplication.getContext()).addToRequestQueue(request);
}
Point 1:
这里获取网络的连接状态使用了到了ConnectionManager,这里我们将网络状态的获取也封装一下:
public class NetWorkUtils {
//定义网络连接的管理器
private static ConnectivityManager mManager = (ConnectivityManager) BaseApplication.getContext().getSystemService(BaseApplication.getContext().CONNECTIVITY_SERVICE);
private static NetworkInfo networkInfo = mManager.getActiveNetworkInfo();;
/**
* 判断网络是否连接
* @return 连接返回true,未连接返回false.
*/
public static boolean isConnection(){
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
return false;
}
/**
* 获得网络连接的类型
* @return 返回网络连接的类型,例如Wifi.
*/
public static String getConnectionType() {
String type = "";
if (networkInfo != null && networkInfo.isConnected()) {
type = networkInfo.getTypeName();
} else {
type = "无网络连接";
}
return type;
}
}
Point 2:
这里使用Volley使用到了单例,因为Volley是使用缓冲池原理,具体参考《Android 网络连接——Volley 》。
public class VolleySingleton {
private static VolleySingleton mInstance;
private RequestQueue mRequestQueue;//消息队列
private ImageLoader mImageLoader;//ImageLoader对象
private static Context mCtx;
private VolleySingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
mImageLoader = getImageLoader();
}
public static synchronized VolleySingleton getInstance(Context context){
if(mInstance == null){
mInstance = new VolleySingleton(context);
}
return mInstance;
}
public RequestQueue getRequestQueue(){
if(mRequestQueue == null){
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
public ImageLoader getImageLoader(){
if(mImageLoader==null){
mImageLoader = new ImageLoader(getRequestQueue(), new ImageLoader.ImageCache(){
private final LruCache<String,Bitmap> cache = new LruCache<String,Bitmap>(20);//设置图片缓存
@Override
public Bitmap getBitmap(String url) {
return null;
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
}
});
}
return mImageLoader;
}
//将请求添加到队列中
public void addToRequestQueue(Request req){
getRequestQueue().add(req);
}
}
通过测试网络连接成功,这样我们网络连接就封装好了。