目录
5Retrofit+OkHTTP+RecycleView的实现步骤
第四步:在activity_main.xml添加Recycle,并给其设置id
1.Retrofit是什么?
准确来说,Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装
原因:
网络请求的工作本质上是
OkHttp
完成,而
Retrofit
仅负责网络请求接口的封装。
App
应用程序通过 Retrofit请求网络,实际上是使用
Retrofit
接口层封装请求参数、
Header
、
Url
等信息,之后由
OkHttp 完成后续的请求操作。在服务端返回数据之后,OkHttp
将原始的结果交给
Retrofit
,
Retrofit
根据用户 的需求对结果进行解析。所以,网络请求的本质仍旧是OkHttp
完成的,
retrofit
只是帮使用者来进行工 作简化的,比如配置网络,处理数据等工作,提高这一系列操作的复用性。这也就是网上流行的一个不 太准确的总结:
OkHttp
是瑞士军刀,
retrofit
则是将瑞士军刀包装成了一个非常好用的指甲钳
2.OkHttp和Retrofit
OKhttp
的意义:
OkHttp
是基于
Http
协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟HttpClient,HttpUrlConnection
的职责是一样的。
OkHttp
的职责:
OkHttp
主要负责
socket
部分的优化,比如多路复用,
buffer
缓存,数据压缩等等。
OkHttp
给用户留下的问题
1.
用户网络请求的接口配置繁琐,尤其是需要配置请求
body
,请求头,参数的时候;
2.
数据解析过程需要用户手动拿到
responsbody
进行解析,不能复用;
3.
无法适配自动进行线程的切换。
使用
Retrofit解决问题
Retrofit
主要负责应用层面的封装,就是说主要面向开发者,方便使用,比如请求参数,响应数据的处 理,错误处理等等。
Retrofit
封装了具体的请求,线程切换以及数据转换。
网上一般都推荐
RxJava+Retrofit+OkHttp
框架,
Retrofit
负责请求的数据和请求的结果,使用接口的
方式呈现,
OkHttp
负责请求的过程,
RxJava
负责异步,各种线程之间的切换,用起来非常便利。

主要的步骤都是:
创建网络请求实体
client->
构建真正的网络请求
->
将网络请求方案与真正的网络请求实体结合构成一个
请求
Call->
执行网络请求
->
处理返回数据
->
处理
Android
平台的线程问题。
在上图中,我们看到的对比最大的区别是什么?
1. OkHttp
创建的是
OkhttpClient,
然而
retrofit
创建的是
Retrofit
实例
2.
构建蓝色的
Requet
的方案
,retrofit
是通过注解来进行的适配
3.
配置
Call
的过程中
,retrofit
是利用
Adapter
适配的
Okhttp
的
Call
4.
相对
okhttp,retrofit
会对
responseBody
进行自动
Gson
解析
5.
相对
okhttp,retrofit
会自动的完成线程的切换
3.Retrofit的使用(异步GET)
1 添加Retrofit库的依赖
由于
Retrofit
是基于
OkHttp
,所以还需要添加
OkHttp
库依赖
implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
2 添加网络权限
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
3 创建接收服务器返回数据的类
PhoneAddress.java
public class PhoneAddress {
private boolean success;
private String tel;
private Info info;
public static class Info{
private String local;
private String duan;
private String type;
private String yys;
private String bz;
@Override
public String toString() {
return "Info{" +
"local='" + local + '\'' +
", duan='" + duan + '\'' +
", type='" + type + '\'' +
", yys='" + yys + '\'' +
", bz='" + bz + '\'' +
'}';
}
}
public void show(){
System.out.println(success);
System.out.println(tel);
System.out.println(info.local);
System.out.println(info.duan);
System.out.println(info.type);
System.out.println(info.yys);
System.out.println(info.bz);
}
@Override
public String toString() {
return "PhoneAddress{" +
"success=" + success +
", tel='" + tel + '\'' +
", info=" + info +
'}';
}
}
4 创建用于描述网络请求的接口
GetRequest_Interface.java
public interface GetRequest_Interface {
@GET("api/phone?")
Call<PhoneAddress> getCall(@Query("tel")String tel);
}
5 创建Retrofit实例
6 创建网络请求接口实例
7 发送网络请求
8 处理返回结果
//创建Retrofit对象
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("https://api.vvhan.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
//创建网络请求接口的实例
GetRequest_Interface request=retrofit.create(GetRequest_Interface.class);
//对发送送请求进行封装
Call<PhoneAddress> call=request.getCall(phonenum);
//发送网络请求(异步)
call.enqueue(new Callback<PhoneAddress>() {
@Override
public void onResponse(Call<PhoneAddress> call, Response<PhoneAddress> response) {
tv_show.setText(response.body().toString());
}
@Override
public void onFailure(Call<PhoneAddress> call, Throwable t) {
Log.i("onFailure","请求失败");
}
});
4 Retrofit的使用(异步POST)
1 添加Retrofit库的依赖
implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
2 添加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
3 创建接收服务器返回数据的类
public class LoginInfo {
private int success;
private String info;
@Override
public String toString() {
return "LoginInfo{" +
"success=" + success +
", info='" + info + '\'' +
'}';
}
}
4 创建用于描述网络请求的接口 (接收请求体)
public interface PostRequest_Interface {
@POST("login")
Call<LoginInfo> postCall(@Body RequestBody requestBody);
}
5 创建Retrofit实例
6 创建网络请求接口实例
7 发送网络请求
8 处理返回结果
private void postData(String num) {
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("http://192.168.17.181:8080/TestWeb_war_exploded/")
.addConverterFactory(GsonConverterFactory.create())
.build();
PostRequest_Interface request=retrofit.create(PostRequest_Interface.class);
MediaType type=MediaType.Companion.parse("application/json;charset=utf-8");
RequestBody body=RequestBody.Companion.create(num,type);
Call<LoginInfo> call=request.postCall(body);
call.enqueue(new Callback<LoginInfo>() {
@Override
public void onResponse(Call<LoginInfo> call, Response<LoginInfo> response) {
Log.i("onResponse",response.body().toString());
}
@Override
public void onFailure(Call<LoginInfo> call, Throwable t) {
Log.i("onFailure","失败");
}
});
}
5Retrofit+OkHTTP+RecycleView的实现步骤
第一步: 创建项目
第二步:导入依赖
implementation "com.github.bumptech.glide:glide:4.12.0"
implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
第三步:添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
第四步:在activity_main.xml添加Recycle,并给其设置id
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:padding="5dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_news"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
第五步:创建子布局 news_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="5dp"
android:padding="5dp"
app:cardElevation="5dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="190dp"
android:layout_margin="5dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/news_show"
android:layout_width="190dp"
android:layout_height="190dp"
app:srcCompat="@drawable/ic_launcher_background" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_marginTop="5dp"
android:id="@+id/news_title"
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:layout_marginTop="20dp"
android:id="@+id/news_desc"
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
第六步:创建实体类
package com.hopu.day23_practice.model;
import java.util.List;
public class News {
private boolean success;
private String title;
private String subtitle;
private String update_time;
private List<Data> data;
public void setSuccess(boolean success) {
this.success = success;
}
public boolean getSuccess() {
return success;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
public String getSubtitle() {
return subtitle;
}
public String getUpdate_time() {
return update_time;
}
public void setUpdate_time(String update_time) {
this.update_time = update_time;
}
public void setData(List<Data> data) {
this.data = data;
}
public List<Data> getData() {
return data;
}
public class Data {
private int index;
private String title;
private String desc;
private String pic;
private String hot;
private String url;
private String mobilUrl;
public void setIndex(int index) {
this.index = index;
}
public int getIndex() {
return index;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getDesc() {
return desc;
}
public void setPic(String pic) {
this.pic = pic;
}
public String getPic() {
return pic;
}
public void setHot(String hot) {
this.hot = hot;
}
public String getHot() {
return hot;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
public void setMobilUrl(String mobilUrl) {
this.mobilUrl = mobilUrl;
}
public String getMobilUrl() {
return mobilUrl;
}
@Override
public String toString() {
return "Data{" +
"index=" + index +
", title='" + title + '\'' +
", desc='" + desc + '\'' +
", pic='" + pic + '\'' +
", hot='" + hot + '\'' +
", url='" + url + '\'' +
", mobilUrl='" + mobilUrl + '\'' +
'}';
}
}
@Override
public String toString() {
return "News{" +
"success=" + success +
", title='" + title + '\'' +
", subtitle='" + subtitle + '\'' +
", update_time='" + update_time + '\'' +
", data=" + data +
'}';
}
}
第七步:创建适配器
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {
List<News.Data> list;
public void setResource(List<News.Data> list){
this.list=list;
notifyDataSetChanged();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item,parent,false);
ViewHolder viewHolder=new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
News.Data data=list.get(position);
Glide.with(holder.view).load(data.getPic()).into(holder.news_show);
holder.news_title.setText(data.getTitle());
holder.news_desc.setText(data.getDesc());
}
@Override
public int getItemCount() {
if (list==null){
return 0;
}else {
return list.size();
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView news_show;
TextView news_title;
TextView news_desc;
View view;
public ViewHolder(@NonNull View itemView) {
super(itemView);
view=itemView;
news_desc=itemView.findViewById(R.id.news_desc);
news_title=itemView.findViewById(R.id.news_title);
news_show=itemView.findViewById(R.id.news_show);
}
}
}
第八步:设置适配器
//声明容器
NewsAdapter newsAdapter;
RecyclerView rv_news;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv_news=findViewById(R.id.rv_news);
newsAdapter=new NewsAdapter();
LinearLayoutManager layoutManager=new LinearLayoutManager(this);
rv_news.setLayoutManager(layoutManager);
rv_news.setAdapter(newsAdapter);
initData();
}
第九步:进行网络请求
1. 创建请求接口
public interface News_Interface {
@GET("api/hotlist?type=zhihuHot")
Call<News> getNews();
}
2. 开始网络请求
3. 处理返回结果
private void initData() {
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("https://api.vvhan.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
News_Interface news_interface=retrofit.create(News_Interface.class);
Call<News> call=news_interface.getNews();
call.enqueue(new Callback<News>() {
@Override
public void onResponse(Call<News> call, Response<News> response) {
Log.i("onResponse",response.body().toString());
newsAdapter.setResource(response.body().getData());
}
@Override
public void onFailure(Call<News> call, Throwable t) {
Log.i("onFailure","请求失败");
}
});
}