目录
1.Retrofit
1.基本用法
他可以配置一个根路径,然后在指定服务器接口地址是只需要使用相对路径即可,这样就不要每次指定完整的URL地址,它还允许我们对服务器接口进行归类,将功能同属一类的服务器接口定义到同一个接口文件中
导入依赖
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
第一个是导入Retrofit,OKHttp和Okio等几个库
第二个是一个Retrofit的转换库
这里定义了一个名字叫APP的类,然后定义它相关的接口,这个接口是负责对服务器相关功能进行归类的
public class App {
private String id;
private String name;
private String version;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
这个类简单的定义了三个私有变量,下面是他的接口
public interface AppService {
@GET("get_data.json")
Call<List<App>> getAppData();
}
@GET("get_data.json")
: 这是一个 Retrofit 的注解,用于指示这是一个 GET 请求。括号中的字符串 "get_data.json"
是相对于 baseUrl
的相对路径,表示我们希望访问的资源。
这个注释表示在调用getAppData是时候Retrofit会发起一条请求,他的相对路径就是括号里面的参数,根路径会在获取Retrofit对象的时候设置
Call<List<App>> getAppData();
: 这是一个接口方法的声明,它定义了返回类型为 Call<List<App>>
。这表示这个方法将返回一个 Call
对象,其中包含了一个 List<App>
。
Call
是 Retrofit 提供的一个用于发起网络请求的对象,它可以异步地发送请求并接收响应。<List<App>>
指定了请求成功时返回的数据类型。在这里,它表示我们期望服务器返回一个包含多个App
对象的列表。
Call
是 Retrofit 中用于处理网络请求的一个关键接口。它代表了一个可执行的 HTTP 请求,可以异步地发送请求并接收服务器的响应。
在 Retrofit 中,每个接口方法的返回类型都是一个 Call
对象。这个 Call
对象包含了发送请求所需的所有信息,并提供了异步执行请求的能力。
Call的作用
- 发起网络请求:
Call
接口的实例可以用于发送网络请求。它可以执行 HTTP 请求并返回服务器的响应。 - 异步执行:
Call
接口提供了enqueue
方法,可以在后台线程中异步地执行网络请求,避免在主线程中进行网络请求可能导致的界面卡顿问题。 - 取消请求:
Call
接口提供了cancel
方法,可以用于取消尚未执行完毕的请求。 - 获取请求信息:可以通过
request()
方法获取到当前请求的相关信息,例如 URL、HTTP 方法等。 - 获取响应:可以通过调用
execute()
方法同步地执行请求并获取响应,或者通过异步回调Callback
获取响应。
然后在布局中设置一个按钮 代码略
在就是在主活动中设置他的点击事件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Button button1 = findViewById(R.id.getAppbutton);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://10.0.2.2/") // 设置基础 URL
.addConverterFactory(GsonConverterFactory.create()) // 使用 Gson 解析器
.build();
// 创建 AppService 接口的实例
AppService appService = retrofit.create(AppService.class);
// 发起网络请求
appService.getAppData().enqueue(new Callback<List<App>>() {
@Override
public void onResponse(Call<List<App>> call, Response<List<App>> response) {
// 请求成功的回调
List<App> list = response.body();
if (list != null) {
for (App app : list) {
// 打印应用信息
Log.d("MainActivity", "id is " + app.getId());
Log.d("MainActivity", "name is " + app.getName());
Log.d("MainActivity", "version is " + app.getVersion());
}
}
}
@Override
public void onFailure(Call<List<App>> call, Throwable t) {
// 请求失败的回调
t.printStackTrace(); // 打印异常信息
}
});
}
});
}
这个代码一段一段进行分析
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://10.0.2.2/") // 设置基础 URL
.addConverterFactory(GsonConverterFactory.create()) // 使用 Gson 解析器
.build();
// 创建 AppService 接口的实例
AppService appService = retrofit.create(AppService.class);
这个是获取了一个Retrofit对象,他的根路径,解析方式如上,然后设置接口实例
// 发起网络请求
appService.getAppData().enqueue(new Callback<List<App>>() {
@Override
public void onResponse(Call<List<App>> call, Response<List<App>> response) {
// 请求成功的回调
List<App> list = response.body();
if (list != null) {
for (App app : list) {
// 打印应用信息
Log.d("MainActivity", "id is " + app.getId());
Log.d("MainActivity", "name is " + app.getName());
Log.d("MainActivity", "version is " + app.getVersion());
}
}
}
@Override
public void onFailure(Call<List<App>> call, Throwable t) {
// 请求失败的回调
t.printStackTrace(); // 打印异常信息
}
调用getAppData方法,返回了一个call 方法,然后调用enqueue方法,将他添加到调度队列中,等待执行,这里new Callback<List<App>>
是创建了一个实现了 Callback<List<App>>
接口的匿名类的实例。这个匿名类是一个回调函数,用于处理网络请求的响应。
Callback<List<App>>
是 Retrofit 中的一个泛型接口。它是用于处理网络请求的回调接口,其中的泛型参数表示了预期响应的数据类型。new Callback<List<App>>() { ... }
创建了一个匿名类实例,该匿名类实现了Callback<List<App>>
接口,并覆写了接口中的方法。这样,你可以在匿名类中定义自己的处理逻辑。
在你的代码中,Callback<List<App>>
表示这是一个处理类型为 List<App>
的回调对象。这意味着在请求成功后,你将获得一个 List<App>
类型的响应数据,可以在 onResponse
方法中进行处理。
总结来说,new Callback<List<App>>()
创建了一个用于处理网络请求响应的回调对象,该回调对象中定义了在请求成功和失败时应该执行的操作。
然后成功和失败的回调函数输出
处理复杂的接口地址类型
1.静态接口地址
GET http://example.com/get_data.json
他的写法如下
public interface AppService {
@GET("get_data.json")
Call<List<App>> getAppData();
}
2.动态接口
-
GET http://example.com/<page>/get_data.json
这个接口中代表页数,我们传入不同的页数,服务器会返回不同的数据,这个在Retrofit的处理如下
public interface AppService { @GET("{page}/get_data.json") Call<List<App>> getAppData(@Path("page") int page); }
在注解指定的接口地址中使用了一个{page}的占位符,然后又在getData()方法中添加了一个page参数,并使用@Path(“page”)这个注解来申明这个参数,这样在调用getData方法进行申请的时候Retrofit就会自动把page参数的值替换到占位符的位置
GET http://example.com/get_data.jasn?u=<user>&t=<token>
这是一种标准带参数的GET请求格式,接口地址的最后使用?来连接参数部分,每个参数都是一个使用等号连接的键值对,多个参数中使用&进行连接,上面地址中要求我们传入user 和taken这俩个参数的值,对于这个Retrofit设置了专门的GET请求
public interface AppService {
@GET("get_data.json")
Call<List<App>> getAppData(
@Query("u") String user,
@Query("t") String token);
}
HTTP常见的请求类型
GET 请求用于从服务器获取地址
POST 请求用于向服务器提交数据
PUT和PATCH 请求用于修改服务器上的数据
DELETE 请求用于删除服务器上的数据
在他们前面加上@即可完成发出相应类型的请求
比如
DELETE http://example.com/data/<id>
public interface AppService {
@DELETE("data/{id}")
Call<ResponseBody> deleteData(@PAth("id") String id)
}
这里ResponseBody,除了EGT其他的更多是操作服务器上的数据,而不是获取服务器上的数据所以他对服务器响应的数据并不关心,这时候ResponseBody表示可以接收任意类型的数据,并不会对响应数据进行解析
提交数据
POST http://example.com/data/create
{"id":1,"context":"The desription for this data "}
public interface AppService {
@POST("data/creat")
Call<ResponseBody> deleteData(@Body Data data);
}