使用Retrofit进行网络请求

技术概述

Retrofit是一个android的网络请求框架,封装于Okhttp,实际上Retrofit是在Okhttp的基础上完成了请求接口的封装。团队项目需要通过网络请求获得用户的数据、菜谱的数据等,需要用到这个技术。Retrofit的一个难点是注解,请求方法、请求头、请求参数等都需要用到注解。

技术详述

添加依赖包

//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'

接下来以用户登录的验证为例:
首先定义一个登录接口

public interface UserServices {
  @POST("user/login")
  Call<UserResponse> getPostUser(@Body RequestBody body);
}

*其中注解使用POST因为需要用户的账号密码作为参数传递给后端验证,参数注解将RB对象转化为字符串传递参数。(一般使用GsonConverterFactory转化)

接着创建一个用户数据Response类

public class UserResponse {
    private String msg;
    private String code;
    private DataBean user;
    private String token;

    //getter
    //setter
    public class DataBean {
        private String user_name;
        private String signature = "";
        private String tags = "";

        //setter
        //getter
    }
}

*封装数据类更方便相关操作

创建Retrofit请求实例

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constant.URL_BASE)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

创建接口请求实例

UserServices userServices = retrofit.create(UserServices.class);
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),new Gson().toJson(map));

请求接口调用

Call<UserResponse> call = userServices.getPostUser(body);
call.enqueue(new Callback<UserResponse>() {
            @Override
            public void onResponse(Call<UserResponse> call, Response<UserResponse> response) {
                if (response.isSuccessful() && response.body().getCode() == null){
                }
//请求成功对得到的数据response.body()进行处理
            }

            @Override
            public void onFailure(Call<UserResponse> call, Throwable t) {
//请求失败
                runOnUiThread(() -> {
                    Toast.makeText(LoginActivity.this,"请求失败",Toast.LENGTH_SHORT).show();
                });
            }
        });

技术使用中遇到的问题和解决过程

    public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }

方法会判断当前线程是否在UI线程,若不在的话,anciton被发送到UI线程的事件队列执行。使用:

runOnUiThread(() -> {
//更新UI
});

总结

网络请求是和后端数据交互的全过程,其中接口、数据的封装都挺重要的,相应的请求体、参数注解什么的虽然比较难但是和资料对照起来也不会有特别复杂的实现。

参考博客

上一篇:java-列出所有地方不再使用的不推荐使用的类/方法的工具?


下一篇:使用本地JSON进行2.0版Android单元测试