实际开发中,网络请求是一个很常用的需求
一款APP需要与服务器传输信息
就要用到网络请求
那么如何开发一款适合自己的网络请求库
就显得十分重要
今天就开始手动封装一个网络请求工具
在开始之前
需要考虑的问题是
1:采用何种框架,是Volley,Okhttp还是其他?
2:如何保证代码的可维护性,在新的项目可以快速应用?
3:在一个框架过时之后,如何快速地替换最新的网络框架?
这里采用接口隔离原则
自己封装了一个请求库
基本可以做到以上三点
在需要替换最新的框架时,不必每一个应用到请求的地方都去修改
而是在一个分离出来的manager类里面去设置即可
那么现在开始编码
首先在我们项目下面新建一个net文件夹
用来存放有关网络请求的所有类
还有一个baen文件夹
用来存储解析出的对象
现在我们开始对net文件夹的工具类进行编写
首先我们新建一个Contants类
用来存放这些请求的url
这里准备了两个url
/**
* Created by Administrator on 2019/11/8.
* 数据接口url
*/
public interface Contants {
//主页引导图
public static final String Get_SPLASH_URL = "http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1";
//天气预报
public static final String Get_TEMPERATURE_URL = "http://wthrcdn.etouch.cn/weather_mini?city=深圳";
}
再新建一个INetManager作为网络请求工具接口
这里先拿基本的get请求做示例
重写的方法需要传入基本的三个参数
url,回调结果,和请求的tag
这个INetGetCallBack是我自己新建的回调接口类
后面会用到
建议对于每个请求类型(get,post,downloadfile)
都去新建一个这样的回调接口类
比如:
INetGetCallBack
INetPostCallBack
/**
* Created by lenovo on 2019/11/8.
* 网络请求工具类
*/
public interface INetManager {
/**
*
* @param url 请求网址
* @param call 回调
* @param tag 请求的tag
*/
void get(String url, INetGetCallBack call, Object tag);
}
INetGetCallBack接口类的内容也很简单
就是一个成功一个失败的方法
/**
* Created by lenovo on 2019/11/8.
* 回调get接口的返回结果
*/
public interface INetGetCallBack {
//成功的回调
void success(String response);
//失败的回调
void failed(Throwable throwable);
}
接下来我们去新建一个INetClient的类
这个类采用单例模式
具体业务中就是使用这个类来请求网络.
这个类里有一个INetManager
他就是不同网络请求框架的接口
这里我们自己编写一个OkhttpNetManager类
用来实现INetManager这个接口
从而通过在INetClient中设置不同的实现类
来对不同的网络请求框架实现快速替换
比如现在要替换VolleyNetManager
就调用setNetManager即可
这样做的好处就是可以快速去修改我们的请求框架
把功能逻辑业务和网络请求业务分离开来
便于维护和迭代
/**
* Created by lenovo on 2019/11/8.
* 请求网络的工具类
*/
public class INetClient {
private static INetClient sInstance = new INetClient();
// 私有化构造方法
private INetClient() {
}
public static INetClient getsInstance() {
return sInstance;
}
//默认使用Okhttp,OkhttpNetManager是INetManager接口的实现类
private INetManager mNetManager = new OkhttpNetManager();
/**
* 这里得到使用的网络请求框架
* @return
*/
public INetManager getmNetManager() {
return mNetManager;
}
/**
* 这里设置使用哪种网络请求框架
* 可以在Application里设置
* 如 Okhttp Volley等
* @param mNetManager
*/
public void setNetManager(INetManager mNetManager) {
this.mNetManager = mNetManager;
}
}
写好了这个实现的工具类
我们就要来对具体的OkhttpNetManager进行编码了
这里采用的Okhttp版本如下:
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
记得加上网络权限
<uses-permission android:name="android.permission.INTERNET"/>
具体实现类如下:
/**
* Created by lenovo on 2019/11/8.
* 接口实现类
* 采用Okhttp进行网络请求
*/
public class OkhttpNetManager implements INetManager {
private static OkHttpClient sokHttpClient;
//主线程的handler
private static Handler shandler = new Handler(Looper.getMainLooper());
static {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//设置请求时间
builder.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS);
sokHttpClient = builder.build();
}
@Override
public void get(String url, final INetGetCallBack callback, Object tag) {
final Request.Builder builder = new Request.Builder();
Request request = builder.url(url).get().tag(tag).build();
Call call = sokHttpClient.newCall(request);
// Response execute = call.execute();//同步操作
//异步操作
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
if (call.isCanceled()) {
return;
}
//非ui线程
shandler.post(new Runnable() {
@Override
public void run() {
//ui线程
callback.failed(e);
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
try {
if (call.isCanceled()) {
return;
}
final String string = response.body().string();
//非ui线程
shandler.post(new Runnable() {
@Override
public void run() {
//ui线程
callback.success(string);
}
});
} catch (Throwable e) {
e.printStackTrace();
callback.failed(e);
}
}
});
}
}
这里是用Okhttp的实现类
也可以采用Volley或者其他请求框架去实现
以后想要替换框架
只需要自己写一个这样的实现类
然后在INetClient设置这个实现类即可
不用在业务逻辑处去逐个修改
现在,基本功能都写完了,只需要调用即可
在MainActivity中如果要进行get请求
只需要写以下代码:
INetClient.getsInstance()
.getmNetManager()//得到具体网络请求实现类,这里是OkhttpNetManager
.get(Contants.Get_TEMPERATURE_URL, new INetGetCallBack() {
@Override
public void success(String response) {
//接口请求成功解析,json
}
@Override
public void failed(Throwable throwable) {
//接口请求失败,打印日志
throwable.printStackTrace();
}
}, MainActivity.this);
到这里,一个基本的符合接口隔离原则的网络框架就封装好了
后面只需要在这个基础上不断地新增不同的方法
如post、downloadfile等
不断地完善即可
如要替换Okhttp
只需要新建一个其他的INetManager实现类就可以了
最后需要注意一个版本适配的问题
使用OkHttp3在Android P 出现的错误:
CLEARTEXT communication to host not permitted by network
具体解决方法见下面博客:
使用OkHttp3在Android P 出现的错误:CLEARTEXT communication to host not permitted by network - 简书