1 Retrofit(HTTP客户端)

1.1 简介

我们项目当中的每个app都需要用到网络和服务器进行交互,在Android项目开发中使用HTTP协议完成通信的话,基本上都要用到OkHttp或者Retrofit。
OkHttp和Retrofit是目前应用最为广泛的网络组件。

1.2 Retrofit是什么?

准确来说,Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。
网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责网络请求接口的封装。App应用程序通过Retrofit请求网络,实际上是使用Retrofit接口层封装请求参数、Header、Url 等信息,之后由 OkHttp完成后续的请求操作。在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析。

1.3 Retrofit的使用 (异步GET)

第一步: 创建项目
第二步:导入依赖
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"?>
<RelativeLayout 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"><androidx.viewpager2.widget.ViewPager2android:id="@+id/vp_head_img"android:layout_width="match_parent"android:layout_height="200dp"/><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_news"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="10dp"android:layout_below="@+id/vp_head_img"/></RelativeLayout>
第五步:创建子布局
<?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="wrap_content"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="150dp"android:layout_margin="5dp"><ImageViewandroid:id="@+id/iv_news"android:layout_width="160dp"android:layout_height="match_parent"android:scaleType="fitXY" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="20dp"android:layout_toEndOf="@+id/iv_news"android:orientation="vertical"><TextViewandroid:id="@+id/tv_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_marginTop="30dp"android:text="text"/><TextViewandroid:id="@+id/tv_desc"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_marginTop="30dp"android:text="text"/></LinearLayout></RelativeLayout></androidx.cardview.widget.CardView>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"><ImageViewandroid:id="@+id/iv_head"android:layout_width="match_parent"android:layout_height="200dp"android:scaleType="fitXY"tools:srcCompat="@tools:sample/avatars" /></RelativeLayout>
第六步:创建实体类
public class News {private boolean success;private String title;private String subtitle;private String update_time;private List<Data> data;public class Data {private int index;private String title;private String pic;private String desc;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 setPic(String pic) {this.pic = pic;}public String getPic() {return pic;}public void setDesc(String desc) {this.desc = desc;}public String getDesc() {return desc;}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;}}public News(List<Data> data) {this.data = data;}public List<Data> getData() {return data;}@Overridepublic String toString() {return "News{" +"success=" + success +", title='" + title + '\'' +", subtitle='" + subtitle + '\'' +", update_time='" + update_time + '\'' +", data=" + data.toString() +'}';}}
public class HeadImg {private boolean success;private String title;private String subtitle;private String update_time;private List<Data> data;public class Data {private int index;private String title;private String pic;private String desc;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 setPic(String pic) {this.pic = pic;}public String getPic() {return pic;}public void setDesc(String desc) {this.desc = desc;}public String getDesc() {return desc;}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;}@Overridepublic String toString() {return "Data{" +"index=" + index +", title='" + title + '\'' +", pic='" + pic + '\'' +", desc='" + desc + '\'' +", url='" + url + '\'' +", mobilUrl='" + mobilUrl + '\'' +'}';}}public HeadImg(List<Data> data) {this.data = data;}public List<Data> getData() {return data;}@Overridepublic String toString() {return "HeadImg{" +"data=" + data +'}';}
}
第七步:创建适配器
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHold> {private List<News.Data> list;public void setList(List<News.Data> list){this.list=list;notifyDataSetChanged();}@NonNull@Overridepublic ViewHold onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent,false);ViewHold viewHold=new ViewHold(view);return viewHold;}@Overridepublic void onBindViewHolder(@NonNull ViewHold holder, int position) {News.Data data=list.get(position);holder.tv_tital.setText(data.getTitle());holder.tv_desc.setText(data.getDesc());Glide.with(holder.view).load(data.getPic()).into(holder.iv_news);}@Overridepublic int getItemCount() {return list == null ? 0 : list.size();}public class ViewHold extends RecyclerView.ViewHolder{TextView tv_tital;TextView tv_desc;ImageView iv_news;View view;public ViewHold(@NonNull View itemView) {super(itemView);this.view=itemView;tv_tital=itemView.findViewById(R.id.tv_title);tv_desc=itemView.findViewById(R.id.tv_desc);iv_news=itemView.findViewById(R.id.iv_news);}}
}
public class HeadImgAdapter extends RecyclerView.Adapter<HeadImgAdapter.ViewHold> {private List<HeadImg.Data> list;public void setList(List<HeadImg.Data> list) {this.list = list;notifyDataSetChanged();}@NonNull@Overridepublic ViewHold onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.head_img_item, parent, false);ViewHold viewHold=new ViewHold(view);return viewHold;}@Overridepublic void onBindViewHolder(@NonNull ViewHold holder, int position) {HeadImg.Data data = list.get(position);Glide.with(holder.view).load(data.getPic()).into(holder.iv_head);}@Overridepublic int getItemCount() {return list == null ? 0 : list.size();}public class ViewHold extends RecyclerView.ViewHolder{ImageView iv_head;View view;public ViewHold(@NonNull View itemView) {super(itemView);this.view=itemView;iv_head=itemView.findViewById(R.id.iv_head);}}}
第九步:创建请求接口

public interface GetRequest_Interface {//https://api.vvhan.com/api/hotlist?type=baiduRD@GET("api/hotlist?type=baiduRD")Call<News> getNews();//https://api.vvhan.com/api/hotlist?type=wxHot@GET("api/hotlist?type=wxHot")Call<HeadImg> getHeadImg();}
第十步:进行网络请求
public class MainActivity extends AppCompatActivity {private ViewPager2 vp_head_img;private RecyclerView rv_news;private LinearLayoutManager layoutManager;private NewsAdapter newsAdapter;private HeadImgAdapter headImgadapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);vp_head_img=findViewById(R.id.vp_head_img);rv_news=findViewById(R.id.rv_news);layoutManager=new LinearLayoutManager(MainActivity.this);newsAdapter=new NewsAdapter();rv_news.setLayoutManager(layoutManager);rv_news.setAdapter(newsAdapter);headImgadapter=new HeadImgAdapter();vp_head_img.setAdapter(headImgadapter);loadNews();loadHeadImg();}private void loadNews() {Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.vvhan.com/").addConverterFactory(GsonConverterFactory.create()).build();GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);Call<News> call = request.getNews();call.enqueue(new Callback<News>() {@Overridepublic void onResponse(Call<News> call, Response<News> response) {newsAdapter.setList(response.body().getData());}@Overridepublic void onFailure(Call<News> call, Throwable t) {Log.i("onFailure","连接失败");}});}private void loadHeadImg() {Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.vvhan.com/").addConverterFactory(GsonConverterFactory.create()).build();GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);Call<HeadImg> call = request.getHeadImg();call.enqueue(new Callback<HeadImg>() {@Overridepublic void onResponse(Call<HeadImg> call, Response<HeadImg> response) {headImgadapter.setList(response.body().getData());Log.i("onResponse","连接成功");}@Overridepublic void onFailure(Call<HeadImg> call, Throwable t) {Log.i("onFailure","连接失败");}});}}

2 RxJAVA(响应式编程)

2.1 简介

2.1.1 响应式编程

响应式编程的一个关键概念是事件。事件可以被等待,可以触发过程,也可以触发其它事件。事件是唯一的以合适的方式将我们的现实世界映射到我们的软件中:如果屋里太热了我们就打开一扇窗户。同样的,当我们的天气app从服务端获取到新的天气数据后,我们需要更新app上展示天气信息的UI;汽车上的车道偏移系统探测到车辆偏移了正常路线就会提醒驾驶者纠正,就是是响应事件。

2.1.2 什么是RxJava

RxJava 是一种响应式编程,来创建基于事件的异步操作库。基于事件流的链式调用、逻辑清晰简
洁。
RxJava 我的理解是将事件从起点(上游)流向终点(下游),中间有很多卡片对数据进操作并传
递,每个卡片获取上一个卡片传递下来的结果然后对事件进行处理然后将结果传递给下一个卡片,
这样事件就从起点通过卡片一次次传递直到流向终点。

2.1.3 什么是观察者模式?

举个栗子,Android中View的点击监听器的实现,View是被观察者,OnClickListener对象是观察者,Activity要如何知道View被点击了?那就是派一个OnClickListener对象,入驻View,与View达成一个订阅关系,一旦View被点击了,就通过OnClickListener对象的OnClick方法传达给Activity。采用观察者模式可以避免去轮询检查,节约有限的cpu资源。

2.2 Retrofit+RxJava的使用

2.2.1 为什么要结合使用

代码简洁
借助 retorfit 加 rxjava,我们就不需要再做其他多余的封装或修改。网络请求写起来就会简单许多,而且结构也清晰。被观察者就是请求的发起,观察者就是请求的回调。
操作符的作用
rxjava 的优势就在于其操作符的使用,我理解的「操作符」就是 rxjava 为我们提供了一系列方法,可以运用在观察者模式中的「被观察者」「观察者」或「订阅过程」之间来控制。实际项目中我遇到过以下几种常见情况,可以用操作符来处理。
1. 请求结果需要做数据处理之后,再给页面展示。 「map」操作符,这个操作符就是在请求回来之后直接对数据做处理之后再返回给观察者。
2. 请求结果是做为下一个请求的请求入参。「flatMap」操作符,这个操作符是在遇到串联请求时使用的,当第一个请求返回结果之后,再拿着结果去请求下一个接口。

2.2.2 实现步骤

第一步: 创建项目
第二步:导入依赖
implementation "com.github.bumptech.glide:glide:4.12.0"//for rxjavaimplementation 'io.reactivex.rxjava2:rxjava:2.2.0'//for rxandroidimplementation 'io.reactivex.rxjava2:rxandroid:2.1.0'//rxjava adapter for retrofitimplementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.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" ><androidx.viewpager2.widget.ViewPager2android:id="@+id/vp_head_img"android:layout_width="match_parent"android:layout_height="200dp"/></LinearLayout>
第五步:创建子布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"><ImageViewandroid:id="@+id/iv_head"android:layout_width="match_parent"android:layout_height="200dp"android:scaleType="fitXY"tools:srcCompat="@tools:sample/avatars" /></RelativeLayout>
第六步:创建实体类
public class HeadImg {private boolean success;private String title;private String subtitle;private String update_time;private List<Data> data;public class Data {private int index;private String title;private String pic;private String desc;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 setPic(String pic) {this.pic = pic;}public String getPic() {return pic;}public void setDesc(String desc) {this.desc = desc;}public String getDesc() {return desc;}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;}@Overridepublic String toString() {return "Data{" +"index=" + index +", title='" + title + '\'' +", pic='" + pic + '\'' +", desc='" + desc + '\'' +", url='" + url + '\'' +", mobilUrl='" + mobilUrl + '\'' +'}';}}public HeadImg(List<Data> data) {this.data = data;}public List<Data> getData() {return data;}@Overridepublic String toString() {return "HeadImg{" +"data=" + data +'}';}
}
第七步:创建适配器
public class HeadImgAdapter extends RecyclerView.Adapter<HeadImgAdapter.ViewHold> {private List<HeadImg.Data> list;public void setobservable(List<HeadImg.Data> list) {this.list = list;notifyDataSetChanged();}@NonNull@Overridepublic ViewHold onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.head_img_item, parent, false);ViewHold viewHold=new ViewHold(view);return viewHold;}@Overridepublic void onBindViewHolder(@NonNull ViewHold holder, int position) {HeadImg.Data data = list.get(position);Glide.with(holder.view).load(data.getPic()).into(holder.iv_head);}@Overridepublic int getItemCount() {return list == null ? 0 : list.size();}public class ViewHold extends RecyclerView.ViewHolder{ImageView iv_head;View view;public ViewHold(@NonNull View itemView) {super(itemView);this.view=itemView;iv_head=itemView.findViewById(R.id.iv_head);}}}
第九步: 创建请求接口
public interface GetRequest_Interface {//https://api.vvhan.com/api/hotlist?type=wxHot@GET("api/hotlist?type=wxHot")Observable<HeadImg> getHeadImg();}

第十步:进行网络请求

public class MainActivity extends AppCompatActivity {private ViewPager2 vp_head_img;private HeadImgAdapter headImgadapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);vp_head_img=findViewById(R.id.vp_head_img);headImgadapter=new HeadImgAdapter();vp_head_img.setAdapter(headImgadapter);loadHeadImg();}private void loadHeadImg() {Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.vvhan.com/").addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);Observable<HeadImg> observable = request.getHeadImg();observable.subscribeOn(Schedulers.io())//在io线程进行网络请求操作.observeOn(AndroidSchedulers.mainThread())//回到主线程 处理请求结果.subscribe(new Observer<HeadImg>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(HeadImg headImg) {headImgadapter.setobservable(headImg.getData());}@Overridepublic void onError(Throwable e) {Log.i("onError","连接失败");}@Overridepublic void onComplete() {Log.i("onComplete","连接完成");}});}}

Android【Retrofit(HTTP客户端),RxJAVA(响应式编程)】相关推荐

  1. Rxjava响应式编程

    一.Rxjava的思维 (1)响应式编程 (根据上一层的响应来影响下一层的变化) Rx全称:reactivex 链式编程:起点-需求1-需求2-......-终点 eg:登录操作: 触发登录按钮(起点 ...

  2. RxJava响应式编程学习笔记

    1.概述 RxJava是一个著名的开源库,是ReactiveX(Reactive Extensions)的一种java实现.ReactiveX是一种响应式扩展框架,有很多实现,如RxAndroid,R ...

  3. Android什么是函数,什么是函数响应式编程(JavaAndroid版本)

    什么是函数响应式编程(Java&Android版本) 函数响应式编程(FRP)为解决现代编程问题提供了全新的视角.一旦理解它,可以极大地简化你的项目,特别是处理嵌套回调的异步事件,复杂的列表过 ...

  4. 响应式编程在Android 中的一些探索

    响应式在前端领域已经变得十分流行,很多主流框架都采用响应式来进行页面的展示刷新.本文主要是探索一下响应式在移动端Android上的一些实践,包括对响应式思想的理解,以及目前Android上实现响应式的 ...

  5. 响应式编程在Android中的应用

    响应式编程简介 响应式编程是一种基于异步数据流概念的编程模式.数据流就像一条河:它可以被观测,被过滤,被操作,或者为新的消费者与另外一条流合并为一条新的流. 响应式编程的一个关键概念是事件.事件可以被 ...

  6. 响应式编程RxJava (一)

    1.什么是RxJava? 1.1什么是响应式编程? 是一种基于异步数据流概念的编程模式(异步数据流编程) 数据流 ->河流(被观测.被过滤.被操作) 1.2响应式编程的设计原则是: 保持数据的不 ...

  7. 响应式编程Rxjava 书籍视频教程

    转载请注明 AIQ - 最专业的机器学习大数据社区 http://www.6aiq.com AIQ 机器学习大数据 知乎专栏 点击关注 响应式编程业界知秋大佬: <Java 编程方法论响应式 之 ...

  8. Android响应式编程RxAndroid(1):简单例程

    Android响应式编程RxAndroid(1):简单例程 响应式Android编程开发,在github上的项目地址:https://github.com/ReactiveX/RxAndroid,设计 ...

  9. Java的HTTP服务端响应式编程

    传统的Servlet模型走到了尽头 传统的Java服务器编程遵循的是J2EE的Servlet规范,是一种基于线程的模型:每一次http请求都由一个线程来处理. 线程模型的缺陷在于,每一条线程都要自行处 ...

最新文章

  1. 发布文件打包springboit_程序安装包咋制作的?Qt程序打包三部曲,从应用程序到安装包...
  2. 对指针变量取地址_C语言指针简介(amp;和*运算符)
  3. python实现字符串切割
  4. 多窗体、窗体传值、打开唯一窗体操作
  5. 多线程-Thread、Runnable、Callbale、Future
  6. 使用npm安装TypeScript
  7. PowerBI 报表服务器刷新失败自动重刷并邮件通知
  8. 不太平凡的2020、平凡的我
  9. 微信开发2之php网页授权登录
  10. winform下自绘提示框风格窗体
  11. 你真的需要 @DirtiesContext?
  12. fail to build phoneME Feature-转
  13. 初创团队如何快速获取种子用户,引爆用户核反应堆?
  14. java中isprime_Java中的Arcane isPrime方法
  15. C#,调用GDI32.DLL绘制图形的源程序
  16. Waited too long for library cache load lock
  17. [附源码]Java计算机毕业设计SSM电商直播订单管理系统
  18. Linux终端-对NTFS文件系统数据丢失后的恢复案例
  19. 校园网络远程登录虚拟机Linux问题解决
  20. 光剑诗集选——2021.2

热门文章

  1. 【程序人生】Java这么卷,你为什么还在坚持?热爱吗?因为穷
  2. 清华小学上册计算机教学案例,案例分析 清华小学 罗远琴
  3. Java面向对象(类的无参和带参)
  4. 输入一行字符,统计其中字母、数字和其他符号的个数。例如,输入:As123 g1b,9 输出:字母个数:4 数字字符个数:5 其他字符个数:2
  5. Azure Synapse Analytics (Azure SQL DW)性能优化指南(1)——使用有序聚集列存储索引优化性能
  6. Lambda 表达式Demoo
  7. 怎么写安卓手机脚本_拉结尔手游攻略,云手机全自动挂机刷副本及装备
  8. 网页作业HTML+CSS+JS大作业——汽车租赁(47页) 加特效 web期末作业设计网页_汽车大学生网页设计作业成品
  9. unity 太阳自发光_unity shader基础之——unity中实现环境光、自发光
  10. 故事工厂在DuerOS技能开发中的应用——百度2019AI开发者大会DuerOS公开课摘要解读之四...