日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

一个MVP+RxJava+Retrofit的干货集中营

發(fā)布時(shí)間:2023/12/20 java 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一个MVP+RxJava+Retrofit的干货集中营 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

歡迎掘金的小伙伴們?cè)L問(wèn)我的博客網(wǎng)站,原文鏈接:wensibo.top/2017/05/15/… ,未經(jīng)允許不得轉(zhuǎn)載!

今天想要與大家一起分享的五月份的時(shí)候用一個(gè)星期開(kāi)發(fā)的一個(gè)app——干貨集中營(yíng)客戶端,因?yàn)橐呀?jīng)獲得了掘金的專欄所以就把之前的文章發(fā)不上來(lái)與大家一起分享。
其實(shí)網(wǎng)上已經(jīng)有許多類似的項(xiàng)目,代碼家也在他的干貨集中營(yíng)中推薦了幾款優(yōu)秀的作品,我也借鑒了其中的一些,自己開(kāi)發(fā)出一款干貨集中營(yíng)客戶端,目前項(xiàng)目已經(jīng)發(fā)布到github,如果你想了解整個(gè)工程的具體內(nèi)容,那么你可以fork或者clone,如果你覺(jué)得我做得還可以,那么請(qǐng)你賜給我一個(gè)star唄!你的支持會(huì)是我努力的動(dòng)力。

前言

慢慢的已經(jīng)養(yǎng)成了每篇文章都會(huì)來(lái)一個(gè)前言,也慢慢地將寫(xiě)文章潛移默化的轉(zhuǎn)變成寫(xiě)故事,所以每個(gè)故事都會(huì)有前言,也都會(huì)有結(jié)果,這次也不例外。
距離上篇引起熱烈反響的文章發(fā)布已經(jīng)過(guò)去一個(gè)月了,承蒙廣大網(wǎng)友對(duì)我的支持以及建議,當(dāng)然作為一個(gè)90后,我也很虛心的接受來(lái)自各方的吐槽,畢竟我并不優(yōu)秀,只是一直在優(yōu)秀的路上努力的奔跑著。下面我想跟大家一起分享一下這一個(gè)月里我做了些什么事,以及接下來(lái)一段時(shí)間的計(jì)劃和打算。

Have Done List

  • 持續(xù)22天在github上出現(xiàn),看看下面這棵貢獻(xiàn)樹(shù)
    contributions
  • 博客瀏覽量突破35000
    blog
  • 看了1本好書(shū)——《網(wǎng)絡(luò)是怎樣連接的》
  • 研究Retrofit與RxJava的源碼(待我葡萄成熟時(shí)再把文章放出來(lái)吧,現(xiàn)在太嫩了,不好意思讓大家看到)
  • 2次擔(dān)任演講的主講人(之后會(huì)寫(xiě)一篇文章講述我的演講技巧)
  • 看了錘子科技新品發(fā)布會(huì)(我是羅粉但也是加油,心疼老羅一秒)
  • 努力尋找實(shí)習(xí)(投了許多簡(jiǎn)歷,但是無(wú)一幸免:sob: ,有同學(xué)可以推薦一波嗎?沒(méi)有的話我待會(huì)再問(wèn)問(wèn))
  • 1個(gè)全新的干貨集中營(yíng)客戶端app(也是寫(xiě)這篇文章的緣由)

Todo List

  • xposed插件開(kāi)發(fā)(這個(gè)閃念是有一天夜里驚醒過(guò)來(lái)的想法)
  • 繼續(xù)寫(xiě)好的文章與大家一起分享,不僅僅是技術(shù)方面的,還有許多我覺(jué)得有用的文章,都會(huì)為大家奉上,感謝老鐵們的支持
  • 繼續(xù)看書(shū)
  • 繼續(xù)找實(shí)習(xí)(嗚嗚嗚~~(>_<)~~,體會(huì)到工作難找了,尤其是互聯(lián)網(wǎng)寒冬)

老鐵別廢話了
好啦,上面講了一大堆廢話終于可以進(jìn)入正題了,我也很基動(dòng),開(kāi)車咯!

項(xiàng)目介紹

logo
GankClient(又稱干貨集中營(yíng)客戶端)是一個(gè)全新的干貨集中營(yíng)客戶端,它獲取的是來(lái)自干貨集中營(yíng)API的數(shù)據(jù),利用全新的Material Design的設(shè)計(jì)語(yǔ)言展示數(shù)據(jù)內(nèi)容。整個(gè)項(xiàng)目采用MVP的設(shè)計(jì)架構(gòu),并且大量使用RxJava2,網(wǎng)絡(luò)框架使用的是Retrofit。我用下面幾個(gè)裝逼的句子來(lái)形容一下這個(gè)APP:
  • 更快速的加載速度
  • 更流暢的頁(yè)面體驗(yàn)
  • 更有趣的刷新效果
  • 更精美的網(wǎng)頁(yè)瀏覽
  • 更美觀的視覺(jué)享受

這個(gè)只是我的個(gè)人感受,大神請(qǐng)輕噴:joy: ,不過(guò)還是希望大家能夠喜歡這個(gè)項(xiàng)目,并且積極的向我pull request以及反饋bug,希望大家多多支持。如果可以的話給個(gè)star咯。

預(yù)覽

誰(shuí)說(shuō)不給圖的

全部效果圖來(lái)一發(fā)

screenshotscreenshotscreenshot
screenshotscreenshotscreenshot

沒(méi)有g(shù)if圖都不好意思說(shuō)話了

gif

下載

酷安基佬群

如果你使用酷安的話,那就使勁點(diǎn)這里,或者在酷安搜索干貨集中營(yíng),認(rèn)準(zhǔn)我的圖標(biāo)哦

干貨集中營(yíng)

fir.im

如果你沒(méi)有安裝酷安,那么你可以掃描下方的二維碼進(jìn)行下載

QRCode

測(cè)試

如果你想測(cè)試這個(gè)項(xiàng)目,那么請(qǐng)手動(dòng)clone

功能&特色

√表示已經(jīng)實(shí)現(xiàn)的功能,X表示的的是還沒(méi)實(shí)現(xiàn)或者需要完善的功能。(吐槽一下,掘金的MarkDown編輯器還是沒(méi)有實(shí)現(xiàn)一些基本的語(yǔ)法,例如打勾勾)

√實(shí)時(shí)獲取服務(wù)器的最新數(shù)據(jù),采用CardView的布局以更好的展現(xiàn)數(shù)據(jù)。
√刷新效果很好玩,真的很精致,感謝Phoenix。
√如果你裝有Chrome瀏覽器,并將其設(shè)置為默認(rèn)瀏覽器,那么你的網(wǎng)頁(yè)瀏覽效果就會(huì)十分酷炫。感謝Custom-Tabs-Client ! 墻裂推薦Chrome,如果你沒(méi)有安裝Chrome,那也沒(méi)關(guān)系,那就用傳統(tǒng)的WebView吧!
√更加統(tǒng)一的過(guò)渡動(dòng)畫(huà),相信你會(huì)愛(ài)上它。
√保存、分享圖片與鏈接,也可以直接使用瀏覽器打開(kāi)鏈接。
√更好看的Material Design設(shè)計(jì)風(fēng)格。
√妹子很漂亮喲!


X優(yōu)化webview的視頻播放。
X增加使用系統(tǒng)瀏覽器的選項(xiàng)。
X修復(fù)在主界面中加載數(shù)據(jù)到2016/4/20左右時(shí)數(shù)據(jù)顯示錯(cuò)亂的問(wèn)題。
X增強(qiáng)分享功能。

分解

終于到了這個(gè)純干貨步驟了,別說(shuō)話先看東西!

如何使用MVP的設(shè)計(jì)架構(gòu)

我先展示以下這個(gè)項(xiàng)目的結(jié)構(gòu)圖,讓大家心里有個(gè)底

  • http
    • GankRetrofit.java
    • GankRetrofitClient.java
  • mvp
    • model
      • BaseModel.java
    • presenter
      • BasePresenter.java
    • view
      • IBaseView.java
  • ui
    • activity
    • adapter
    • base
    • chromeviews
    • fragment
    • widget

可以看到,整個(gè)項(xiàng)目的結(jié)構(gòu)還算比較清晰,整體的架構(gòu)都是在mvp目錄中定下來(lái)的,mvp架構(gòu)分三層,model模型層,用于定義一些數(shù)據(jù)的類型;presenter呈現(xiàn)者層,用于處理view層的邏輯;view顯示層,這里定義的都是接口,真正實(shí)現(xiàn)他們的是activity,這些activity只要實(shí)現(xiàn)相應(yīng)的接口,就能夠自己復(fù)寫(xiě)其中的方法。
當(dāng)然我這么說(shuō)你肯定還是一臉懵逼,而且我還必須跟你說(shuō),我這個(gè)不算最純粹的MVP模式,最純粹的寫(xiě)法應(yīng)該都是面向接口編程的,就是在model,presenter,以及view下都是定義接口,而到了具體的運(yùn)用場(chǎng)景,就定義出具體的類去實(shí)現(xiàn)這些接口。當(dāng)然了,為了讓大家能夠更清楚MVP是怎么實(shí)現(xiàn)的,下面我會(huì)用代碼的形式為大家展示,例如我要編寫(xiě)MainActivity的代碼,首先已經(jīng)知道在這個(gè)Activity中需要做如下這些事:

  • 初始化組件
  • 加載Fragment
  • FloatingActionButton的點(diǎn)擊事件——去到DailyActivity
  • drawer menu的點(diǎn)擊事件——去到AboutActivity

為了讓Activity專注于界面的工作,而不用去考慮邏輯處理的操作,這個(gè)就是所謂的解耦,那么我們可以將邏輯的操作放到presenter中去,而與界面有關(guān)的操作就放在view下,于是我們就可以這樣寫(xiě)(為了便于大家理解,我將項(xiàng)目中的代碼做了適當(dāng)?shù)男薷?#xff0c;如果你想了解更加具體的邏輯,可以仔細(xì)看看代碼):

  • IBaseView
public interface IBaseView {//界面初始化操作void init(); }復(fù)制代碼
  • BasePresenter&MainPresenter
/** * 將presenter的公共操作集成為BasePresenter */ public abstract class BasePresenter <T extends IBaseView>{protected Disposable disposable;protected Context context;protected T iView; //獲取到view的對(duì)象public BasePresenter(Context context, T iView) {this.context = context;this.iView = iView;}public void init() {iView.init();}public abstract void release();public abstract void initPresenter(); }/** * 每一個(gè)界面都可以編寫(xiě)自己的Presenter,并指定View的泛型 */ public class MainPresenter extends BasePresenter<IBaseView> {public MainPresenter(Context context, IBaseView iView) {super(context, iView);}@Overridepublic void release() {}public void toDailyActivity() {Intent intent = new Intent(context, DailyActivity.class);context.startActivity(intent);}public void toAboutActivity() {Intent intent = new Intent(context, AboutActivity.class);context.startActivity(intent);}public void toSettingActivity() {Intent intent = new Intent(context, SettingActivity.class);context.startActivity(intent);}復(fù)制代碼
  • MainActivity
public class MainActivity <MainPresenter> extends AppCompatActivity implements IBaseView{@OnClick(R.id.fab_main)void fabClick() {presenter.toDailyActivity();}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overrideprotected void initPresenter() {presenter = new MainPresenter(this, this);presenter.init();}@Overridepublic void init() {//所有的初始化操作}@Overrideprotected void onDestroy() {super.onDestroy();presenter.release();}}復(fù)制代碼

大概就是這樣一個(gè)套路,講真我這樣講你肯定迷糊,我當(dāng)初在學(xué)這個(gè)的時(shí)候也是十分凌亂,后來(lái)才發(fā)現(xiàn)只有自己動(dòng)手親自敲代碼才能了解整個(gè)思路,另外大家在學(xué)習(xí)MVP的過(guò)程中應(yīng)該擅于畫(huà)圖,不管是在紙上畫(huà)還是使用思維導(dǎo)圖都行,這樣可以讓你更加宏觀的了解整個(gè)調(diào)用的順序以及各個(gè)類之間的關(guān)系,這絕不是你看了一篇文章就能懂的。

你真的用好RxJava了嗎

當(dāng)我問(wèn)這個(gè)問(wèn)題的時(shí)候,其實(shí)我想說(shuō)的是RxJava的用處很廣,我們想當(dāng)然的認(rèn)為只要RxJava與Retrofit相配合就算是完成任務(wù)了,但實(shí)際上只要涉及到耗時(shí)操作、線程切換:網(wǎng)絡(luò)請(qǐng)求、圖片解析、數(shù)據(jù)庫(kù)讀取等等需要用多個(gè)線程一起完成的工作時(shí),你都可以用到RxJava,并且如果你還一直用RxJava1的話,那么你也OUT啦,當(dāng)你認(rèn)識(shí)RxJava2.x的時(shí)候你會(huì)發(fā)現(xiàn)他更強(qiáng)大了。關(guān)于RxJava,我后續(xù)會(huì)寫(xiě)相關(guān)的文章與大家一起分享,這里我舉項(xiàng)目中遇到的一個(gè)例子,看看RxJava的用武之地是多么的廣:

/** * 將圖片保存在本地 */ public void openWebView(final Gank gank) {disposable=Observable.create(new ObservableOnSubscribe() {@Overridepublic void subscribe(@NonNull ObservableEmitter e) throws Exception {e.onNext(android.R.drawable.ic_menu_share);}}).subscribeOn(Schedulers.newThread())//開(kāi)啟一個(gè)新線程來(lái)進(jìn)行耗時(shí)操作.map(new Function<Integer, Bitmap>() {@Overridepublic Bitmap apply(@NonNull Integer integer) throws Exception {//將資源id解析為bitmap是一個(gè)耗時(shí)操作return BitmapFactory.decodeResource(activity.getResources(), integer);}}).observeOn(AndroidSchedulers.mainThread())//回到主線程操作bitmap.subscribe(new Consumer<Bitmap>() {@Overridepublic void accept(@NonNull Bitmap bitmap) throws Exception {//拿到bitmap之后做的界面更新}}); }//釋放資源 public void release() {if (disposable != null&&!disposable.isDisposed()) {disposable.dispose();}}復(fù)制代碼

爽快的Retrofit

還記得之前我寫(xiě)過(guò)Volley的一系列文章,雖然覺(jué)得這個(gè)開(kāi)源框架已經(jīng)不錯(cuò)了,但畢竟長(zhǎng)江后浪推前浪,在Retrofit的面前,Volley簡(jiǎn)直就是小巫見(jiàn)大巫,看看我們應(yīng)該如何在項(xiàng)目中使用:

  • 1、新建一個(gè)接口,用注解的形式在里面定義網(wǎng)絡(luò)請(qǐng)求的方法:
public interface GankRetrofit {//獲取MainActivity界面的數(shù)據(jù),具體的請(qǐng)求路徑應(yīng)該詳細(xì)看官方的API說(shuō)明,// Retrofit與RxJava配合之后才能顯示出更強(qiáng)的威力@GET("data/{type}/40/{page}")Observable<MainData> getMainData(@Path("type") String type, @Path("page") int page); }復(fù)制代碼
  • 2、獲得實(shí)例:
Gson date_gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create(); Retrofit retrofit = new Retrofit.Builder().baseUrl("http://gank.io/api/") //指定服務(wù)器地址.addConverterFactory(GsonConverterFactory.create(date_gson)) //添加一個(gè)gson的解析器.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 如果想使用RxJava那就需要添加這個(gè)適配器 .build(); GankRetrofit gankRetrofit; gankRetrofit = retrofit.create(GankRetrofit.class); //獲取GankRetrofit的對(duì)象復(fù)制代碼
  • 3、獲取數(shù)據(jù):
//返回的Observable<MainData>對(duì)象就可以使用RxJava進(jìn)行解析了 gankRetrofit.getMainData("Android",40);復(fù)制代碼

更好的網(wǎng)頁(yè)瀏覽體驗(yàn)——Custom-Tabs-Client

如果你使用過(guò)Chrome瀏覽器,那么你應(yīng)該會(huì)喜歡上它,當(dāng)我們?cè)谑褂脀ebview開(kāi)發(fā)的時(shí)候,會(huì)發(fā)現(xiàn)webview存在許多的限制,并且開(kāi)發(fā)者對(duì)webview不能完全控制,于是Chrome團(tuán)隊(duì)為了解決開(kāi)發(fā)者的這些問(wèn)題,就設(shè)計(jì)出這個(gè)開(kāi)源庫(kù),只要用戶手機(jī)上安裝Chrome并且設(shè)置為默認(rèn)瀏覽器,那么打開(kāi)網(wǎng)頁(yè)鏈接的時(shí)候就會(huì)看到如下的畫(huà)面:

custom-tabs-client
是的!如此酷炫的畫(huà)面是用到了Chrome瀏覽器的內(nèi)核,并且讀取Chrome的cookie,例如如果你在Chrome已經(jīng)登錄過(guò)github了,那么通過(guò)這個(gè)庫(kù)打開(kāi)的github鏈接同樣也顯示你已經(jīng)登錄了github。當(dāng)然除了頁(yè)面效果十分好之外,我們還可以自定義許多東西,例如過(guò)渡動(dòng)畫(huà)ToolBar上方的ActionButton等等,我的項(xiàng)目中也已經(jīng)實(shí)現(xiàn)了這兩個(gè)功能。接下來(lái)我?guī)Т蠹乙黄鹂纯醋詈?jiǎn)單的實(shí)例應(yīng)該怎么編寫(xiě): CustomTabsIntent.Builder customTabsIntent;customTabsIntent = new CustomTabsIntent.Builder(); //獲取到CustomTabsIntent實(shí)例//一系列的設(shè)置 customTabsIntent.setToolbarColor(activity.getResources().getColor(R.color.colorPrimaryDark)); //設(shè)置ToolBar的顏色 customTabsIntent.setShowTitle(true); //設(shè)置是否顯示網(wǎng)頁(yè)的標(biāo)題 customTabsIntent.setStartAnimations(activity, R.anim.slide_in_right, R.anim.slide_out_left); //設(shè)置進(jìn)入的動(dòng)畫(huà) customTabsIntent.setExitAnimations(activity, R.anim.slide_in_left,R.anim.slide_out_right); //設(shè)置退出的動(dòng)畫(huà) //開(kāi)啟網(wǎng)頁(yè) CustomTabActivityHelper.openCustomTab(activity, //當(dāng)前的activitycustomTabsIntent.build(),view,gank, //gank帶有要打開(kāi)的網(wǎng)頁(yè)的urlnew CustomFallback() { //如果用戶沒(méi)有安裝Chrome并將其設(shè)置為默認(rèn)瀏覽器的話,應(yīng)該做這樣的處理@Overridepublic void openUri(Activity activity, View view,Gank gank) {Log.d("Gank", gank.toString());super.openUri(activity, view,gank);}});復(fù)制代碼

以上就是想要跟大家一起分享的關(guān)于這個(gè)項(xiàng)目中一些重要的點(diǎn),可能有些地方講得并不那么清楚,但我覺(jué)得只有實(shí)踐才能出真知,所以老哥還是乖乖打開(kāi)AS擼擼代碼啦!

版本控制

目前app的版本為V1.0.0,我會(huì)用下面的時(shí)間表記錄版本的迭代,如果有更新的版本,我會(huì)及時(shí)更新這個(gè)表格。

VersionDate
V1.0.02017/5/14

致謝

作為一名Android開(kāi)發(fā)者,我們都應(yīng)該具有像羅老師一樣感激開(kāi)源世界的情懷,而我們現(xiàn)在能做的就是同樣為開(kāi)源世界做貢獻(xiàn),無(wú)論是寫(xiě)文章亦或是寫(xiě)程序,記得都要時(shí)刻保持一顆感恩的心。非常感謝代碼家以及他的干活集中營(yíng),也非常感謝許多前輩們做過(guò)的干活集中營(yíng)app。

  • 代碼家
  • 干貨集中營(yíng)
  • Gank.lu

后記

最近一個(gè)月,感覺(jué)自己身體被掏空,吐槽學(xué)校對(duì)我們專業(yè)的課程安排如此不合理,每天上那些自己不感興趣的課程確實(shí)很無(wú)趣,但是生活再難也要感激它,只有通過(guò)自己的雙手去努力,將來(lái)的你才會(huì)為現(xiàn)在的自己喝彩驕傲。下篇文章再見(jiàn)!

總結(jié)

以上是生活随笔為你收集整理的一个MVP+RxJava+Retrofit的干货集中营的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。