Retrofit网络请求库

本文主要是参考慕课网Jennynick老师视频所做出的总结。

一、首先明白一点:
Retrofit是基于Okhttp网络框架进行的二次封装,其本质仍是Okhttp。(类似乌尔奇奥拉的二段归刃)
另外,科普一下,Android5.0之后不再使用HttpClient了。本来还想着看看httpclient的高阶用法呢,你看,多学习就可以少学习。

二、同Volley对比
Volley基于HttpUrlConnction,Google官方推出,只适用于轻量级网络交互,不适合大文件下载上传场景。
没有对比就没有伤害,伤害了Volley突出了Retrofit如下优点:
API设计简洁易用、注解化配置高度解耦、支持多种解析器、支持Rxjava
实际操作:
一、依赖包导入

    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.okhttp3:okhttp:3.10.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.0.2'

网络权限别忘了申请~

二、创建接口设置请求类型与参数
ex:新建UserInfoModel类和UserMgrService接口:

@GET("login")
public Call<UserInfoModel> login(@Query("username") String username,@Query("pwd") String pwd);

(login是UserMgrService里的一个方法)


三、创建Retrofit对象、设置数据解析器
Retrofit retrofit=new Retrofit.Builder().baseUrl(Constants.BASE_URL).addConverterFactory(GsonConverterFactory.create())).build();
数据解析器支持类型有:
Gson、Jackson、Simple XML、 Protobuf、Moshi、Wire、Scalars
四、生成接口对象
UserMgrService service=retrofit.create(UserMgrService.class);
五、调用接口方法返回Call对象
Call call=service.login(“zhangsan”,“2345”);
六、发送请求(同步、异步)
同步:调用Call对象的execute(),返回结果的响应体(如果是耗时操作,可能导致ANR,需要处理)
异步:调用Call对象的enqueue(),参数是一个回调


请求方法有如下几个:
@GET 表示这个一个get请求
@POST 表示这是一个post请求
@PUT …
@DELETE …
@HEAD …
@OPTIONS …
@PATCH …
请求参数如下:
@Headers 添加请求头
@Path 替换路径
@Query 替代参数值,通常是结合get请求的
@FormUrlEncoded 用表单数据提交
@Field 替换参数值,是结合post请求的
@Body 可以用来提交 Json 数据或者上传文件
@QueryMap:包含多个@Query注解参数(传递较多参数时使用)

GET请求

七、请求实例:
① 新建一个接口,声明请求方法
② 在activity中声明retrofit,并调用接口里的方法。
测试调用github的api:(以下Demo均是在此Url基础上拼接

https://api.github.com/

无参:(最简单的get请求

   @GET("/")//不传参数
   Call<ResponseBody> getMessages();

@Path替换路径:(URL中有参数

@GET("repos/{owner}/{repo}")//路径为:https://api.github.com/repos/{owner}/{repo}
 Call<ResponseBody> getMessages3(@Path("owner") String owner,@Path("repo") String repo);//替换路径

@Path和@Query一块使用:(URL中有参数且URL问号之后有参数

  @GET("users/{user}/repos")//路径:https://api.github.com/users/{user}/repos{?type,page,per_page,sort}
    Call<ResponseBody> getMessages4(@Path("user") String user,
                                    @Query("page") int page,@Query("per_page")int per_page);

@QueryMap的使用(URL中问号之后有多个参数且个数不固定

 @GET("users/{user}/repos")
    Call<ResponseBody> getMessages5(@Path("user") String user, @QueryMap HashMap<String,Integer> info);
   _________________________________
  HashMap<String,Integer> params=new HashMap<>();
                params.put("page",1);
                params.put("per_page",3);
                Call<ResponseBody> call=api.getMessages5("SprrowZ",params);

好,今天先更到这里。
继续来个实例:

public interface GithubApi {
    /**
     * GET请求
     * @return
     */
    //访问文件地址:https://raw.githubusercontent.com/SprrowZ(用户名)/AndroidZex(仓库名)/master(分支)/.gitignore(路径)
    @GET("/")//不传参数
    Call<ResponseBody> getMessages();
    @GET("users/SprrowZ")//这个参数是用来拼路径的,https://api.github.com/users/{user},就是这里的{user}
    Call<ResponseBody> getMessages2();
    @GET("repos/{owner}/{repo}")//路径为:https://api.github.com/repos/{owner}/{repo},{owner}/{repo}
    Call<ResponseBody> getMessages3(@Path("owner") String owner,@Path("repo") String repo);//替换路径
    @GET("users/{user}/repos")//路径:https://api.github.com/users/{user}/repos{?type,page,per_page,sort}
    Call<ResponseBody> getMessages4(@Path("user") String user,
                                    @Query("page") int page,@Query("per_page")int per_page);
    @GET("users/{user}/repos")
    Call<ResponseBody> getMessages5(@Path("user") String user, @QueryMap HashMap<String,Integer> info);




}

    private void retrofitGet1() {
        new Thread(()->{
                Retrofit retrofit=new Retrofit.Builder()
                        .baseUrl(Constant.GITHUB_BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();
                GithubApi service=retrofit.create(GithubApi.class);
                Call<ResponseBody> call=service.getMessages();
                call.enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                        System.out.println(response.body().toString());
                        try {
                            content1.setText("get无参:"+"\n"+response.body().string());
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {
                        t.printStackTrace();
                    }
                });
        }).start();

    }

重点讲一下这个:.addConverterFactory(GsonConverterFactory.create())Converter就是Retrofit为我们提供用于将ResponseBody转换为我们想要的类型,看最上面我们接受返回类型的时候不是ResponseBody而是UserInfoModel,这个类是我们建的实体类,用来接受返回的数据,当数据不复杂时用这个更方便操作,如果复杂的话直接用ResponseBody比较好,个人感觉。。

FBI WARNING
response.body().string()只有第一次有取到值!!!!所以务必赋值给一个String ,然后操作这个对象!
如果不信的话,可以打两个log,都输出response.body().string()你就会发现第二次没有值,这个是正常的,看源码就晓得了,节省资源的策略。

POST请求

Post请求需要把请求参数放置在请求体中,而非拼接在url后面,先介绍两个注解:
@FormUrlEncoded将会自动将请求参数的类型调整为application/x-www-form-urlencoded,需要注意的是:FormUrlEncoded不能用于Get请求。这个注解主要是和@Field配合使用的,@Field注解将每一个请求参数都存放至请求体中,还可以添加encoded参数,该参数为boolean;@FormUrlEncoded 与 @FieldMap注解结合表示以表单的方式传递键值对

猜你喜欢

转载自blog.csdn.net/qq_24820437/article/details/81979565