Android Retrofit网络请求框架

简介

Retrofit是一个网络请求框架,是对okhttp的进一步封装,支持同步和异步、支持多种数据的解析(默认使用Gson),也支持RxJava。
官网地址
github地址

使用步骤

1、添加依赖与权限

1.1在build.gradle(:app)添加Retrofit库依赖

在这里插入图片描述

    //retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

导入的这两个包,第一个是retrofit的本体,第二个是gson的转换器(转换器有很多种)

1.2在AndroidManifest.xml添加网络权限

在这里插入图片描述

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

如果没添加去请求网络就会报错E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
在这里插入图片描述

2、创建Retrofit请求基础配置

    //创建Retrofit实例
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://api.github.com/")//设置网络请求的Url地址
            .addConverterFactory(GsonConverterFactory.create())//设置数据解析器(Gson转换器)
            .build();

上面代码构造了一个Retrofit对象,值得注意的是baseUrl不能为空,且最好以 / 斜杠结尾,这样后面第4步创建网络请求接口的时候,就不用每次在每个网络请求接口里都写 / 斜杠了
Retrofit把网络请求的URL分成了两部分,前半部分放在Retrofit对象里(一般一个项目的前半部分都是一样的),后半部分放在网络请求接口里(就比如放在@GET的注解里面,但是如果网络请求接口里的URL是一个完整的网址,那么Retrofit对象里的URL可以不写)
每次要去请求的时候,都要创建一个Retrofit,那其实可以封装一下这段代码

/**
 * 接口管理器
 */
public class ApiServiceManager {

    private Retrofit mRetrofit;

    private static ApiServiceManager mInstance = new ApiServiceManager();

    public static ApiServiceManager get() {
        return mInstance;
    }

    private ApiServiceManager() {
        //创建Retrofit实例
        mRetrofit = new Retrofit.Builder()
                .baseUrl(UrlConfig.BASE_URL) //设置网络请求的Url地址
                .addConverterFactory(GsonConverterFactory.create()) //设置数据解析器(支持Gson解析转换器)
                .build();
    }

    /**
     * 创建对应的ApiService
     *
     * @param service 接口类
     */
    public <T> T create(final Class<T> service) {
        return mRetrofit.create(service);
    }

    /** 获取Retrofit对象 */
    public Retrofit getRetrofit() {
        return mRetrofit;
    }
}

里面的UrlConfig.BASE_URL也是我把地址单独放起来了

/**
 * 地址配置
 */
public class UrlConfig {

    private UrlConfig() {
    }

    /**
     * 接口路径
     */
    @Keep
    private static class BaseUrls {
        /**
         * Github地址
         */
        @Keep
        private static final String Github = "https://api.github.com/";
        /**
         * 获取QQ的地址
         */
        @Keep
        private static final String UOMG = "https://api.uomg.com/";
    }

    /**
     * 接口地址
     */
    public static final String BASE_URL = BaseUrls.Github;

}

其实呢在网络请求的时候,最首要的,就是要确定我们需要访问的网络路径
本文有两个案例,一个是获取Github用户数据,一个是获取QQ用户数据
获取Github用户数据的路径:https://api.github.com/users/hongyangAndroid
点此访问
其中
https://api.github.com/可以当作共用的接口地址先存起来,如上面代码的Github,后文获取Github用户数据的时候就用这个地址,后面的地址可以在第4步创建网络请求接口的时候把剩下的写了
hongyangAndroid可以换成需要访问的Github(这里借用一下hongyang大神的)
获取QQ用户数据的路径:https://api.uomg.com/api/qq.info?qq=774740085
点此访问
https://api.uomg.com/后文获取QQ用户数据的时候就用这个地址
其中774740085可以换成需要访问的QQ
这里使用的是免费的API接口
知道了需要访问的网络路径以后,可以先在浏览器访问看看,这样可以确定接口返回数据的结构,以此来编写数据返回后的Bean类(步骤3)
这是访问的Github的
在这里插入图片描述
这是访问的QQ的
在这里插入图片描述

3、创建数据返回后的Bean类

因为要讲解两个案例,所以新建了两个Bean类
根据上文访问接口,看见了返回的数据,所以编写数据类如下

/**
 * Github数据类
 */
public class GithubBean {

    /**
     * 登录名字
     */
    public String login;
}

/**
 * QQ数据类
 */
public class QqBean {

    /**
     * QQ名字
     */
    public String name = "";
}

其实还可以这样写

/**
 * Github数据类
 */
public class GithubBean {

    /**
     * 登录名字
     */
    private String login;

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }
}

通过get()和set()方法更安全

4、创建网络请求的接口

先展示一下代码

/**
 * 接口
 */
public interface ApiService {
    //获取Github用户数据
    @GET("users/{user}")//@GET注解的作用:采用Get方法发送网络请求,请求的地址为:BASE_URL+"users/{user}"
    Call<GithubBean> getGithubData(@Path("user") String user);//getGithubData()接收网络请求数据的方法
    //返回类型为Call<*>,*是接收数据的类(即GithubBean类)

    //获取QQ用户数据
    @GET("api/qq.info")
    Call<QqBean> getQqData(@Query("qq") String qq);
}

网络请求接口要根据网络请求地址来创建,要严格和后台对上,不能多符号啊空格什么的。
@GET注解里传入的就是网络请求的部分URL地址(如步骤2所说),这地址的前半部分在Retrofit对象
这一步其实就是把API接口地址转化成一个Java接口,其实Retrofit就是通过注解将HTTP转化为Java接口。
在上面代码中出现的@GET@Path@Query就是注释,下面先来了解一下这些注释吧
网络请求方法类注解
HTTP请求主要分为Get和Post两种方法。
@GET就是采用Get方法发送网络请求
@POST就是采用Post方法发送网络请求
当然还有比如==@HEAD==等,不常用,本文就不介绍了
网络请求参数类注解(本文只介绍@GET,其他的可以百度都有)
比如上面的代码中的@GET("users/{user}")@GET("api/qq.info")就都是使用Get请求方式
Get请求方式是把参数是放在路径当中的
比如获取Github用户数据的路径:https://api.github.com/users/hongyangAndroid
获取QQ用户数据的路径:https://api.uomg.com/api/qq.info?qq=774740085
最后面跟着的,就是请求参数
那么怎么拼接请求参数到路径里面呢?
@Path用于URL地址的缺省值
代码:

    @GET("users/{user}")
    Call<GithubBean> getGithubData(@Path("user") String user);

在访问Github用户数据的路径:https://api.github.com/users/hongyangAndroid的时候
因为前面写了BASE_URL,所以一起拼接起来的路径是https://api.github.com/users/{user}
里面的{user}会被替换为getGithubData()方法的第一个参数user
@Query用于@GET方法的查询参数(Query可以等于Url的?后面的key-value,就很像占位符那样)
比如获取QQ用户数据的路径:https://api.uomg.com/api/qq.info?qq=774740085里面的
?qq=774740085就可以用==@Query==
代码:

    @GET("api/qq.info")
    Call<QqBean> getQqData(@Query("qq") String qq);

请求头类注解标记类注解(就先不介绍了,可以自行百度,以后说不定会在本文中更新的)

5、请求网络(异步、同步)

GET异步请求
请求Github用户数据

    private void getGithubData() {
        //发送异步请求
        //创建网络请求接口的实例
        ApiService apiService = ApiServiceManager.get().create(ApiService.class);
        //对发送请求进行封装
        Call<GithubBean> call = apiService.getGithubData("hongyangAndroid");
        call.enqueue(new Callback<GithubBean>() {
            @Override
            public void onResponse(Call<GithubBean> call, Response<GithubBean> response) {
                //网络请求成功
                if (response.body() == null) {
                    mBinding.contentTv.setText("无数据");
                    return;
                }
                GithubBean githubBean = response.body();
                mBinding.contentTv.setText(githubBean.login);
            }

            @Override
            public void onFailure(Call<GithubBean> call, Throwable t) {
                //网络请求失败
                mBinding.contentTv.setText(t.getMessage());
            }
        });
    }

运行展示:
在这里插入图片描述
获取QQ用户数据

    private void getQqData() {
        ApiService apiService = ApiServiceManager.get().create(ApiService.class);
        Call<QqBean> call = apiService.getQqData("774740085");
        call.enqueue(new Callback<QqBean>() {
            @Override
            public void onResponse(Call<QqBean> call, Response<QqBean> response) {
                if (response.body() == null) {
                    mBinding.contentTv.setText("无数据");
                    return;
                }
                QqBean qqBean = response.body();
                mBinding.contentTv.setText(qqBean.name);
            }

            @Override
            public void onFailure(Call<QqBean> call, Throwable t) {
                mBinding.contentTv.setText(t.getMessage());
            }
        });
    }

运行展示:
在这里插入图片描述
GET同步请求

    private void getQqDataSync() {
        ApiService apiService = ApiServiceManager.get().create(ApiService.class);
        Call<QqBean> call = apiService.getQqData("774740085");
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Response<QqBean> response = call.execute();//同步请求网络
                    if (response.body() == null) {
                        Log.e("TAG", "无数据");
                        return;
                    }
                    QqBean qqBean = response.body();
                    Log.e("TAG", "name=" + qqBean.name);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

注意Android主线程不能操作网络请求。
运行结果
在这里插入图片描述

拓展

Retrofit是基于Okhttp开发的网络请求框架,所以有一部分如请求超时时间、拦截器、代理等功能依然需要使用Okhttp的方式来配置,那么如何配置呢?
在ApiServiceManager里添加一下就可以啦
在这里插入图片描述

/**
 * 接口管理器
 */
public class ApiServiceManager {

	private ApiServiceManager() {
        //创建Retrofit实例
        mRetrofit = new Retrofit.Builder()
                .baseUrl(UrlConfig.BASE_URL) //设置网络请求的Url地址
                .addConverterFactory(GsonConverterFactory.create()) //设置数据解析器(支持Gson解析转换器)
                .client(getOkHttpClient())//OkHttpClient
                .build();
    }
	
    /**
     * 获取一个OkHttpClient
     */
    private OkHttpClient getOkHttpClient() {
        return new OkHttpClient.Builder()
                .connectTimeout(100, TimeUnit.SECONDS)//连接超时
                .writeTimeout(100, TimeUnit.SECONDS)//读取超时
                .readTimeout(100, TimeUnit.SECONDS)//写入超时
                .build();
    }
}

Retrofit和RxJava的结合可以参考本人的另一篇文章

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值