Android【Retrofit(HTTP客户端),RxJAVA(响应式编程)】
生活随笔
收集整理的這篇文章主要介紹了
Android【Retrofit(HTTP客户端),RxJAVA(响应式编程)】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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. 請求結果是做為下一個請求的請求入參?!?/span>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(响应式编程)】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Compile、Make和Build的区
- 下一篇: md5验证文件完整性