Android网络框架实际上还挺多的,像volley,okhttp, retrofit这些比较常见的。
常见网络框架
Volley 是Google官方推出的轻量级的网络框架,适用于频繁的的小数据传输,不适合大文件上传。
Okhttp 是Square公司推出的http请求封装库,它的职责跟 HttpUrlConnection 是一样的。
Retrofit 同样是Square 公司推出的,基于 OkHttp 封装的一套 RESTful 网络请求框架。里面涉及到一些设计模式,可以通过注解直接配置请求,可以使用不同 Converter 解析器来序列化数据,同时提供对 RxJava 的支持。
常见的搭配使用是 Retrofit + OkHttp + RxJava ,写起来很简洁,但是有门槛,有一定的基础才比较好理解。
其实okhttp能满足大部分需求,新手入门推荐这个框架,比较容易理解和使用。这也是我之前为什么一直用这个框架的原因。
Retrofit + RxJava
言归正传,简单介绍下这个组合。
Retrofit 可以对Okhttp response响应进行封装。
以本项目登录模块为例,只使用okhttp是这样写的
@Override
public void requestServer(final Context context, String account, String password, final OnGetLoginResultListener onGetLoginResultListener) {
final OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.build();
FormBody body = new FormBody.Builder()
.add("AccountNumber", account)
.add("Password", password)
.build();
final Request request = new Request.Builder()
.url(Constans.SERVER_IP_ADDRESS + "LoginServlet")
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
if (!NetStateCheckHelper.isNetWork(context)) {
onGetLoginResultListener.isNoNet();
}
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String info = response.body().string();
System.out.println(info);
try {
JSONObject jsonObject = new JSONObject(info);
String result = jsonObject.getString("Result");
if ("failed".equals(result)) {
onGetLoginResultListener.isNotExistUser();
}else if ("success".equals(result)){
boolean isLogin = jsonObject.getBoolean("IsLogin");
User user = new Gson().fromJson(jsonObject.getString("User"), User.class);
new UserInfoStore().saveUser(context, user);
System.out.println("onResponse: " + user.getId() + " ; " + user.getAccountNumber() + " ; " + user.getPassword() + " ; " + user.getName() + " ; " + user.getSex() + " ; " + user.getIdentity() + " ; " + user.getDepartment());
if (isLogin) {
// 同步信息
syncInfo(jsonObject.getString("planNail"),
jsonObject.getString("planPullNail"),
jsonObject.getString("planWeek"),
jsonObject.getString("planMonth"),
jsonObject.getString("moodGoodNail"),
jsonObject.getString("moodBadNail"),
jsonObject.getString("moodWeek"),
jsonObject.getString("moodMonth"),
jsonObject.getString("crack"));
}
onGetLoginResultListener.onSuccess(user);
}
} catch (JSONException e) {
onGetLoginResultListener.onFailed();
e.printStackTrace();
}
}
});
}
实现步骤如下:
1.创建client
2.构建body,传入post参数
3.构建request,配置url
4.调用enqueue进行异步请求,在onResponse中获取response.body(),通过Gson手动解析数据。
最终数据通过:listener接口 -> presenter的view接口 -> activity里handler线程切换 -> 主线程显示 。4层传递,最终显示出来。
那有没有一个能很方便切换线程的工具呢?没错,就是rxJava。
rxJava通过观察者模式简化了异步请求中线程切换的代码。
也就是说,使用rxJava可以不用写又长又臭的handler了!!这样只需要3层传递即可,
具体使用
先导入依赖,需要注意的是,这些依赖有很多版本,如果版本搭配不一样会报错。
// retrofit + okhttp 网络请求
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okio:okio:2.1.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
// retrofit数据解析器gson
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
// retrofit + rxjava需要添加的
implementation 'com.squareup.retrofit2:adapter-rxjava:2.0.1'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.2.1'
先写一个请求接口,这个接口定义配置了请求url和post数据以及网络请求的结果实体
@POST("LoginServlet") 请求方法和路径。这个路径和baseUrl会拼接成完整的请求地址。
@FormUrlEncoded post请求需要加上这个注解,不然会报错。
@Field post请求带上的参数,这里登录需要传入账号密码。
Observable<LoginModel> LoginModel是服务器返回数据的实体类,自己定义的
public interface ILoginService {
@POST("LoginServlet")
@FormUrlEncoded
Observable<LoginModel> doLogin(@Field("AccountNumber") String account, @Field("Password") String password);
}
使用retrofit 也有固定的模式。
1.创建retrofit 对象,配置baseUrl,解析器,rxJava。
2.通过retrofit.create创建请求接口
3.请求接口调用请求方法,订阅事件,在onNext()方法里处理结果
public void doLogin(String account, String password, final IOnLoginReqListener listener) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constans.SERVER_IP_ADDRESS)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
ILoginService service = retrofit.create(ILoginService.class);
service.doLogin(account, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<LoginModel>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
if (!NetStateCheckHelper.isNetWork(mContext)) {
listener.isNoNet();
}
e.printStackTrace();
}
@Override
public void onNext(LoginModel loginModel) {
String result = loginModel.getResult();
if ("failed".equals(result)) {
listener.isNotExistUser();
} else if ("success".equals(result)){
boolean isLogin = loginModel.getLogin();
User user = loginModel.getUser();
new UserInfoStore().saveUser(mContext, user);
if (isLogin) {
// 同步信息
sync(loginModel.getPlanNail(),
loginModel.getPlanPullNail(),
loginModel.getPlanWeek(),
loginModel.getPlanMonth(),
loginModel.getMoodGoodNail(),
loginModel.getMoodBadNail(),
loginModel.getMoodWeek(),
loginModel.getMoodMonth(),
loginModel.getCrack());
}
listener.onSuccess(user);
}
}
});
}
总结
使用Retrofit + rxJava代替Okhttp的原因:
1.Retrofit + rxJava链式编程,结构清晰,易于理解
2.rxJava线程切换更简单
3.网络请求处理响应数据更简单了,因为Retrofit 已经为我们转换了。
最后一点,程序员当然要与时俱进!!什么热门学什么,虽然这两个已经火了有一段时间了。。
网友评论