网络请求必不可少的库
使用
1.引入依赖
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
//两个版本号要相同
2.添加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
3.创建一个接口用于存放请求
public interface Ask {
@GET("index")
Call<ResponseBody> get();
}
//接口的名称可以随便取
//@GET:请求的方法,最终请求的网址是baseURL+GET括号内的链接
//函数:表示返回一个Call<ResponseBody>类型的值,通过这个值进行请求操作
4.创建Retrofit对象设置baseURL和Converter(baseURL必须以 / 结尾)
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.baidu.com/")
//自动的Gson解析器
.addConverterFactory(GsonConverterFactory.create())
.build();
5.创建请求接口的对象
Ask ask = retrofit.create(Ask.class);
6.用接口对象获取具体请求对象
Call<ResponseBody> call = ask.get();
7.开始异步请求
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
定义自己的数据接收类
我们还可以自己定义一个类用于接收返回的数据
先贴一下我用Apache编写的json数据
这里我根据json数据类型建了一个MyBean类
public class MyBean {
private int id;
private String version;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在Ask接口中修改
@GET("get_data.json")
Call<List<MyBean>> get();
然后在MainActivity中
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.21.34/")
.addConverterFactory(GsonConverterFactory.create())
.build();
Ask ask = retrofit.create(Ask.class);
Call<List<MyBean>> call = ask.get();
call.enqueue(new Callback<List<MyBean>>() {
@Override
public void onResponse(Call<List<MyBean>> call, Response<List<MyBean>> response) {
Log.d(TAG,response.body().get(0).getId() + "");
}
@Override
public void onFailure(Call<List<MyBean>> call, Throwable t) {
Log.d(TAG,t.getMessage());
}
});
进阶用法
1.路径替换@Path
可以在函数里指定请求地址
@GET("{name}")
Call<List<MyBean>> get2(@Path("name") String name);
//GET里的内容和Path里的内容必须一样
//最终请求的路径就是baseURL+函数中的参数
//比如Call<MyBean> call = ask.get2("get_data.json"),那么最终的请求地址是http://192.168.21.34/get_data.json
2.带参地址@Query
@GET("movieTop")
Call<MyBean> get(@Query("start") int start, @Query("count") int count);
Call<MyBean> call = ask.get(1, 5);
//请求的地址是这样:http://192.168.21.34/movieTop?start=1&count=5
3.向服务器发送@POST和@Body
@POST("get_data.json")
Call<List<MyBean>> send(@Body MyBean myBean);
MainActivity中
Call<List<MyBean>> call3 = ask.send(myBean);
call3.enqueue(new Callback<List<MyBean>>() {
@Override
public void onResponse(Call<List<MyBean>> call, Response<List<MyBean>> response) {
Log.d(TAG, "onResponse: ");
}
@Override
public void onFailure(Call<List<MyBean>> call, Throwable t) {
Log.d(TAG, t.getMessage());
}
});
更进一步
1.表单(FormUrlEncoded)
我们可以使用@FormUrlEncoded注解来发送表单数据。使用 @Field注解和参数来指定每个表单项的Key,value为参数的值。
@FormUrlEncoded
@POST("user/login")
Call<User> updateUser(@Field("username") String name, @Field("password") String pass);
2.单文件上传(Multipart)
@Multipart
@POST("register")
Call<User> registerUser(
@Part MultipartBody.Part headPhoto,
@Part("username") RequestBody userName,
@Part("password") RequestBody passWord
);
//使用
MediaType textType = MediaType.parse("text/plain");
RequestBody name = RequestBody.create(textType, "二傻子");
RequestBody pass = RequestBody.create(textType, "123456");
RequestBody photoRequestBody = RequestBody.create(MediaType.parse("image/png"), 文件对象);
MultipartBody.Part photo = MultipartBody.Part.createFormData("上传的key", "文件名.png", photoRequestBody);
Call<User> call = url.registerUser(photo,name, pass);
//@Part 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型;