美文网首页
Android项目HeartWall优化(二) Retrofit

Android项目HeartWall优化(二) Retrofit

作者: 天上有明月 | 来源:发表于2019-04-22 23:37 被阅读0次

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 已经为我们转换了。

最后一点,程序员当然要与时俱进!!什么热门学什么,虽然这两个已经火了有一段时间了。。

相关文章

网友评论

      本文标题:Android项目HeartWall优化(二) Retrofit

      本文链接:https://www.haomeiwen.com/subject/cljpgqtx.html