IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android Retrofit网络请求框架 -> 正文阅读

[移动开发]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,那其实可以封装一下这段代码

/**
 * 接口管理器
 */
public class ApiServiceManager {
    private Retrofit mRetrofit;
    private static ApiServiceManager mInstance;

    public static ApiServiceManager get() {
        return mInstance = new ApiServiceManager();
    }

    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);
    }

}

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

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

    private UrlConfig() {
    }

    /**
     * 接口路径
     */
    @Keep
    private static class BaseUrls {
//        /**
//         * 正式地址
//         */
//        @Keep
//        private static final String RELEASE = "https://www.baidu.com/";
//        /**
//         * 测试地址
//         */
//        @Keep
//        private static final String Test = "https://www.baidu.com/";
        /**
         * Github地址
         */
        @Keep
        private static final String Github = "https://api.github.com/";
        /**
         * QQ地址
         */
        @Keep
        private static final String QQ = "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);
}

网络请求接口要根据网络请求地址来创建,要严格和后台对上,不能多符号啊空格什么的。
这一步其实就是把API接口地址转化成一个Java接口,其实Retrofit就是通过注解将HTTP转化为Java接口。
在上面代码中出现的@GET@Path@Query就是注释,下面先来了解一下这些注释吧
网络请求方法类注解
HTTP请求主要分为Get和Post两种方法。
@GET就是采用Get方法发送网络请求
@POST就是采用Post方法发送网络请求
当然还有比如==@HEAD==等,不常用,本文就不介绍了
网络请求参数类注解(只介绍一些,其他的可以百度都有)
比如上面的代码中的@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);

Post的请求是把参数放在请求体当中,所以需要用到==@Body==
获取随机土味情话的路径:https://api.uomg.com/api/rand.qinghua

    //获取随机土味情话
    @POST("api/rand.qinghua")
    Call<QhBean> getQhData(@Body RequestBody requestBody);

@Body一般有4个种类,这里讲解自定义创建的
首先,在接口处设置@Body RequestBody requestBody
其次,需要手动解析Response请求返回
有时候我们不需要使用GsonConverterFactory帮我们解析Body数据,我们希望自己能操作数据并且解析。比如获取下载数据的流,我们需要使用ResponseBody类(这个类是OkHttp返回Body类)。

/**
 * 基础请求类
 */
public class RequestBean<T> {

    /**
     * 数据格式
     */
    private static final String ACTION_MEDIATYPE = "application/json; charset=utf-8";
    /**
     * 请求体数据结构
     */
    public T data;

    /**
     * 创建一个请求对象
     */
    public RequestBody createRequestBody() {
        return RequestBody.create(MediaType.parse(ACTION_MEDIATYPE), JSON.toJSONString(this));
    }

    /**
     * 创建默认请求对象
     */
    public static RequestBody createDefaultRequestBody() {
        return RequestBody.create(MediaType.parse(ACTION_MEDIATYPE), "{}");
    }

    /**
     * 创建List请求对象
     *
     * @param list 数组
     */
    public static RequestBody createListRequestBody(List list) {
        return RequestBody.create(MediaType.parse(ACTION_MEDIATYPE), JSON.toJSONString(list));
    }
}

这里使用alibaba的fastjson解析数据,所以还需要添加依赖

    implementation 'com.alibaba:fastjson:1.2.75'

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

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主线程不能操作网络请求。
运行结果
在这里插入图片描述
POST异步请求

    private void getQhData() {
        ApiService apiService = ApiServiceManager.get().create(ApiService.class);
        Call<QhBean> call = apiService.getQhData(RequestBean.createDefaultRequestBody());
        call.enqueue(new Callback<QhBean>() {
            @Override
            public void onResponse(Call<QhBean> call, Response<QhBean> response) {
                if (response.body() == null) {
                    mBinding.contentTv.setText("无数据");
                    return;
                }
                QhBean qhBean = response.body();
                mBinding.contentTv.setText(qhBean.content);
            }

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

在这里插入图片描述

拓展

Retrofit是基于Okhttp开发的网络请求框架,所以有一部分如请求超时时间、拦截器、代理等功能依然需要使用Okhttp的方式来配置,那么如何配置呢?

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

    /** 接口日志标签 */
    public static final String TAG = "resultValue";

    private Retrofit mRetrofit;
    private static ApiServiceManager mInstance;

    public static ApiServiceManager get() {
        return mInstance = new 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)//写入超时
//                .addInterceptor(new RequestInterceptor())//设置拦截器
                .build();
    }

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

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

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-06 09:57:05  更:2021-08-06 09:57:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 10:49:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码