官方介绍
Type-safe HTTP client for Android and Java - 用于Android和Java的类型安全的HTTP客户端。
加载新手教程
Retrofit译为“改进”,改进了啥?实际上Retrofit是基于OkHttp网络框架的封装。
首先我们来看看,使用Retrofit发送一个请求的大概流程:
- 我们使用Retrofit的接口层对URL、请求方式、请求参数、Header等进行封装
- Retrofit使用OkHttp完成真正的请求操作
- OkHttp将服务器返回的数据提供给Retrofit
- Retrofit根据我们的需求去解析数据。
进入新手教程
简单介绍完Retrofit之后,让我们来看看具体应该怎么使用&&一起完成一个搜索古诗小Demo
搜索古诗小Demo
首先我们打开Android Studio,新建RetrofitDemo项目
添加依赖
//Retrofit库
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
获取最新版本请移步Retrofit Github官方地址
在
activity_main.xml
布局文件中添加以下控件并根据自己喜好排版
3个TextView:title标题、author作者、content内容
1个EditText 编辑框
1个Button 按钮
1个ProgressBar 进度条(可要可不要)
然后在MainActivity
中将实例化他们-
搜索古诗API
https://api.apiopen.top/searchPoetry?name=
这里我用的是简书用户有梦想的程序丶猿老哥提供的免费开放接口API(点击跳转)
新建古诗实体类Poetry
这里给大家推荐一款实用小插件GsonFormat
,它可以帮我们快速生成一个实体类
安装方式:File - Settings... - Plugins - 搜索GsonFormat
- 点击右侧绿色Install plugin按钮
等待安装完成重启Android Stdio就可以使用了
使用方式:在浏览器中打开https://api.apiopen.top/searchPoetry?name=静夜思,将返回的整个JSON数据复制,然后回到Poetry类中,按下alt+ins
选择GsonFormat,将内容粘贴到这里,然后点OK,就能看到GsonFormat帮我们自动生成好的实体类内容了~
public class Poetry {
/**
* code : 200
* message : 成功!
* result : [{"title":"静夜思","content":"床前看月光,疑是地上霜。|举头望山月,低头思故乡。","authors":"李白"}]
*/
private int code;
private String message;
private List<ResultBean> result;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<ResultBean> getResult() {
return result;
}
public void setResult(List<ResultBean> result) {
this.result = result;
}
public static class ResultBean {
/**
* title : 静夜思
* content : 床前看月光,疑是地上霜。|举头望山月,低头思故乡。
* authors : 李白
*/
private String title;
private String content;
private String authors;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAuthors() {
return authors;
}
public void setAuthors(String authors) {
this.authors = authors;
}
}
}
- 在
MainActivity
中创建Retrofit实例
Retrofit retrofit = new Retrofit.Builder() //创建Retrofit实例
.baseUrl("https://api.apiopen.top/") //这里需要传入url的域名部分
.addConverterFactory(GsonConverterFactory.create()) //返回的数据经过转换工厂转换成我们想要的数据,最常用的就是Gson
.build(); //构建实例
我们期望请求返回的结果Retrofit能帮我们加工成刚才定义的实体类,所以我们需要添加Gson转换工厂,使用GsonConverterFactory之前我们需要先添加以下依赖
//将刚才添加的retrofit依赖库中的retrofit替换成converter-gson即可
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
- 新建一个RetrofitService接口类,用于定义所有网络请求
在本案例中,我们使用的是一个GET请求,让我们来看看怎么去定义这个请求
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface RetrofitService {
//get请求接口
@GET("searchPoetry") //指定请求类型的注解
Call<Poetry> getPoetry(@Query("name") String name); //获取古诗的方法
}
首先我们在获取古诗方法的上面添加了一个GET注解,并在括号里传入了url的后半段,也就是你要访问前面域名baseUrl下的哪个文件(接口)
相应的,Retrofit肯定也为我们提供了@POST/@PUT等注解,用法相同
然后我们定义了一个返回类型为Call实体的方法getPoetry,并指定其泛型为Poetry类,紧接着我们看到这个方法的传入参数为@Query("name") String name,再次观察url的最后一部分searchPoetry?name=静夜思
,不难发现,name=静夜思
中的name就是@Query("name")注解,而静夜思就是我们传入的String字符串,原来Retrofit会帮我们自动处理好,我们只需要把api接口需要的参数用@Query注解标记,然后传值就可以了,除了@Query,再介绍一些Retrofit为我们提供的常用注解:
GET请求
@QueryMap :传入参数较多时,可以把参数放在Map中
……
POST
@Body:将一整个对象作为请求体
@Field:表单数据键值对传输
具体用法请阅读Retrofit官方文档
- 接下来我们将在
MainActivity
中完成实现接口类 → 使用接口类中的请求方法获取一个Call对象 → 使用Call对象发送请求并编写回调Callback逻辑,由于我在代码中已经为大部分步骤写好了注释,所以直接贴上MainActivity
代码
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
private TextView title; //古诗标题
private TextView author; //古诗作者
private TextView content; //古诗内容
private EditText editText; //编辑框
private Button find; //查找古诗按钮
private RetrofitService service; //请求接口
private ProgressBar progressBar; //进度条
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定控件
title = findViewById(R.id.title);
author = findViewById(R.id.author);
content = findViewById(R.id.content);
editText = findViewById(R.id.edit_text);
find = findViewById(R.id.button);
progressBar = findViewById(R.id.progress_bar);
Retrofit retrofit = new Retrofit.Builder() //创建Retrofit实例
.baseUrl("https://api.apiopen.top/") //url头部
.addConverterFactory(GsonConverterFactory.create()) //返回的数据经过转换工厂转换成我们想要的数据,最常用的就是Gson
.build(); //构建实例
service = retrofit.create(RetrofitService.class); //使用retrofit的create()方法实现请求接口类
find.setOnClickListener(new View.OnClickListener() { //设置按钮点击事件
@Override
public void onClick(View v) {
progressBar.setVisibility(View.VISIBLE); //进度条显示
request();
}
});
}
//请求古诗的方法
private void request() {
Call<Poetry> call = service.getPoetry(editText.getText().toString()); //通过getPoetry()方法获取Call对象
call.enqueue(new Callback<Poetry>() { //call入列发送请求,传入回调Callback,重写成功onRespons()与失败onFailure()方法,并编写相应逻辑
/**
* 请求成功
* */
@Override
public void onResponse(Call<Poetry> call, Response<Poetry> response) { //返回的response中包含了所有信息,其中response.body就是响应主体
if (response.body().getResult().size() > 0) { //由于我们已经添加了Gson转换工厂,所以响应主体会被转换成Poetry对象,使用对象响应方法判断返回的古诗是否大于一首
title.setText(response.body().getResult().get(0).getTitle()); //数据展示
author.setText(response.body().getResult().get(0).getAuthors());
String contentText = response.body().getResult().get(0).getContent().replace("|", "\n"); //由于接口返回的古诗体用"|"代替换行,所以我们想要换行输出就要替换回来
content.setText(contentText);
} else {
Toast.makeText(MainActivity.this, "这就触及到我的知识盲区了", Toast.LENGTH_SHORT).show(); //古诗没有大于一首
}
progressBar.setVisibility(View.INVISIBLE); //进度条隐藏
}
/**
* 请求失败
* */
@Override
public void onFailure(Call<Poetry> call, Throwable t) {
progressBar.setVisibility(View.INVISIBLE); //进度条隐藏
Log.d("ManiActivity", t.getMessage()); //控制台打印报错原因
}
});
}
}
- 最后一步
也是经常容易忘记的一步,在AndroidManifest.xml
中添加网络请求权限
<uses-permission android:name="android.permission.INTERNET"/>
新手教程结束
对于Retrofit本篇仅是了解个入门,更多Retrofit的用法还需继续学习!