Android 网络请求框架(三) Retrofit

Retrofit底层基于OkHttp实现,使用运行时注解提供功能,本文主要内容为其基本使用

build.gradle配置

Java8支持

android {
	......
    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
}

依赖

    //添加retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.7.0'
    //添加gson解析  平时用的基本都是返回值为Gson类型数据,故添加此依赖
    //若想用其他类型数据  自行添加
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'

AndroidManifest.xml添加网络权限

<uses-permission android:name="android.permission.INTERNET"/>

Retrofit的注解分为三大类,分别是HTTP请求方法注解、标记类注解和参数类注解。HTTP注解有8种,即GET、POST这些,标记类注解有3种,FormUrlEncoded、Multipart、Streaming。下载文件时建议使用Streaming注解。参数类注解有有Header、Headers、Body、Path、Field、FieldMap、Part、PartMap、Query和QueryMap等。

HTTP注解之GET请求

HTTP注解为GET
参数类注解主要为QueryQueryMap

简单请求接口 @Query
当参数较少时可以使用该注解

public interface GetRequest {
    @GET("s")//请求方法注解   接口使用百度搜索,只需wd参数即可
    Call<ResponseBody> getCall(@Query("wd") String wd);
}

Retrofit默认将String转换成Json obj,如果不需要gson转换,那么就指定泛型为ResponseBody,且不要设置gson转换器

动态配置URL @Path
该注解支持任何HTTP请求
上面的代码可改为:

public interface GetRequest {
    @GET("{path}")//此处的path会被参数path替换
    Call<ResponseBody> getCall(
    				@Path("path") String path,
    				@Query("wd") String wd);
}

查询条件组 @QueryMap
当有多个请求参数时可以考虑使用该注解
上面的代码可改为:

public interface GetRequest {
    @GET("{path}")
    Call<ResponseBody> getCall(
    				@path("path") String path,
    				@QueryMap Map<String, String> parameter);
}

创建Retrofit

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.baidu.com/")
                .build();
                //实际Url = baseUrl + 请求接口的Url
                //即  "https://www.baidu.com/wd=Android"

Retrofit动态代理获取到定义的接口

        GetRequest getRequest = retrofit.create(GetRequest.class);

返回Call对象

		//百度搜索Android
        Call<ResponseBody> call = getRequest.getCall("Android");

异步调用(该回调运行于UI线程)

        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    Log.d(TAG,response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.e(TAG,t.getMessage()+"");
            }
        });

同步调用

    call.enecute(xxx);

中断请求

	call.cancel();

看起来貌似和OkHttp差不多,做一个小例子

GET请求例子

请求使用的接口为免费天气API接口

    @GET("{path}")
    Call<WeatherBean> getCall(
            @Path("path") String path,
            @QueryMap Map<String, String> map);


    private void queryMap(){
        Map<String, String> ks = new HashMap<>();
        ks.put("version","v1");
        ks.put("appsecret","你的appsecret");
        ks.put("appid","你的appid");
        ks.put("city","欲查询地区");
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.tianqiapi.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        retrofit.create(GetRequest.class)
                .getCall("api",ks)
                .enqueue(new Callback<WeatherBean>() {
                    @Override
                    public void onResponse(Call<WeatherBean> call, Response<WeatherBean> response) {
                        Log.d(TAG,response.body().getUpdate_time());
                    }

                    @Override
                    public void onFailure(Call<WeatherBean> call, Throwable t) {
                        Log.e(TAG,t.getMessage());
                    }
        });
    }

HTTP注解之POST请求

HTTP注解为POST
标记类注解主要为FormUrlEncoded
参数类注解主要为FieldFieldMap
如果服务器支持Json字符串参数,参数类注解也可以使用Body

请求流程与GET基本一致,直接上例子

POST请求例子

简单使用(使用接口为开源社区登录接口)

参数 类型 必填
name String
passwd String

接口请求返回结果如下

{
    "code": 200,
    "message": "成功!",
    "result": {
        "apikey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "email": "[email protected]"
    }
}

两种请求接口方式
方式一

    @FormUrlEncoded
    @POST("developerLogin")
    Call<K> login(@Field("name") String name,
                  @Field("passwd") String pwd);

如果参数为表单则需要加上@FormUrlEncoded,忘记添加则报错:
@Field parameters can only be used with form encoding.

方式二

    @POST("developerLogin")
    Call<K> login(@Query("name") String name,
                  @Query("passwd") String pwd);

GET和POST参数都可以使用@Query注解
请求方法

    private void login(){
        String name = username.getText().toString().trim();
        String pwd = password.getText().toString().trim();
        if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(pwd)){
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("https://api.apiopen.top/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
            retrofit.create(GetRequest.class)
                    .login(name, pwd)
                    .enqueue(new Callback<K>() {
                    @Override
                    public void onResponse(Call<K> call, Response<K> response) {
                        Log.i(TAG,response.body().getResult().getApikey());
                    }

                    @Override
                    public void onFailure(Call<K> call, Throwable t) {
                        Log.e(TAG,t.getMessage());
                    }
            });
        }
    }
发布了13 篇原创文章 · 获赞 2 · 访问量 1102

猜你喜欢

转载自blog.csdn.net/AneTist/article/details/103785989