WanAndroid實戰(zhàn)——網(wǎng)絡(luò)判斷

前情回顧:

1.WanAndroid實戰(zhàn)——首頁Banner

2.WanAndroid實戰(zhàn)——首頁文章

3.WanAndroid實戰(zhàn)——內(nèi)容顯示

4.WanAndroid實戰(zhàn)——刷新加載

前面一直都是在理想環(huán)境(有網(wǎng)絡(luò)連接)下的狀態(tài),當沒有網(wǎng)絡(luò)的時候,將無法獲取數(shù)據(jù)配喳,此時界面顯示不友好锌奴,今天來處理這個問題螃成。效果圖先行:

添加網(wǎng)絡(luò)判斷

在關(guān)閉Wi-Fi時舶斧,打開應(yīng)用今缚,會顯示指定的布局调窍,點擊“重新加載”,會刷新數(shù)據(jù),同時對SmartRefereshLayout的Header和Footer做了修改莽龟,當沒有網(wǎng)絡(luò)的時候顯示“刷新失敗”蠕嫁,“加載失敗”,更準確的進行了顯示轧房。

無網(wǎng)絡(luò)時的error頁面

在首次進入時拌阴,因為機器沒有連接網(wǎng)絡(luò),所以無法獲取到數(shù)據(jù)奶镶,此時應(yīng)該顯示error頁面迟赃。最近看文章時看到了布局優(yōu)化方面的內(nèi)容,有介紹到ViewStub厂镇,剛好這里可以使用纤壁,也可以練練手。

1.在主頁布局文件activity_main.xml根布局中添加ViewStub

    <ViewStub
        android:id="@+id/net_error_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout="@layout/net_error"
        />

關(guān)于ViewStub是如何實現(xiàn)布局優(yōu)化的捺信,和include又有哪些不同酌媒,這些知識大家可以自行學習(我是偷偷的學過了),效率這種東西迄靠,能優(yōu)化的還是優(yōu)化吧秒咨,養(yǎng)成好的習慣,

net_error.xml為真正顯示的內(nèi)容掌挚。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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"
    >


    <TextView
        android:id="@+id/net_error"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawableTop="@drawable/net_error"
        android:drawablePadding="@dimen/net_error_drawable_padding"
        android:gravity="center"
        android:text="@string/net_error_message"
        android:textSize="@dimen/common_text_size"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <TextView
        android:id="@+id/net_refresh"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/net_refresh_margin_top"
        android:background="@drawable/refresh_background"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center"
        android:paddingStart="@dimen/net_refresh_padding_start_and_end"
        android:paddingTop="@dimen/net_refresh_padding_top_and_bottom"
        android:paddingEnd="@dimen/net_refresh_padding_start_and_end"
        android:paddingBottom="@dimen/net_refresh_padding_top_and_bottom"
        android:text="@string/net_error_refresh"
        android:textColor="@color/net_refresh_color"
        android:textSize="@dimen/common_text_size"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/net_error"/>


</android.support.constraint.ConstraintLayout>

net_error的textView中的圖片數(shù)據(jù)加載失敗是在iconfont中下載的雨席,里面圖標很多,大家可以選擇自己認為好看的來使用吠式;net_refresh的background是自己寫的一個shape陡厘,也是很簡單的,其它就是普通的內(nèi)容特占,效果如下:

net_error.png

2.在MainActivity.java中添加邏輯處理

啟動過程的流程如下圖所示糙置,根據(jù)圖示,可以很清楚的來敲代碼了是目。

啟動流程圖.png

在初始化數(shù)據(jù)時判斷網(wǎng)絡(luò)連接谤饭,根據(jù)網(wǎng)絡(luò)狀況進行處理,核心代碼如下:

    /**
     * <p>獲取數(shù)據(jù)</p>
     */
    private void initData() {
        if (NetworkUtils.isConnected()) {

            mPresenter.loadBanner();
            mPresenter.refreshArticle();
            showNormal();
        }
        else {
            showNetError();
        }
    }
    
    /**
     * <p>顯示無網(wǎng)絡(luò)時的布局</p>
     */
    private void showNetError() {
        if (mNetErrorLayout != null) {
            mMainBanner.setVisibility(View.GONE);
            mRefreshLayout.setVisibility(View.GONE);
            mNetErrorLayout.setVisibility(View.VISIBLE);
            return;
        }
        mMainBanner.setVisibility(View.GONE);
        mRefreshLayout.setVisibility(View.GONE);
        mNetErrorLayout = findViewById(R.id.net_error_layout);
        View view = mNetErrorLayout.inflate();
        mNetRefresh = view.findViewById(R.id.net_refresh);
        mNetRefresh.setOnClickListener(v -> {
            if (NetworkUtils.isConnected()) {

                mPresenter.refreshArticle();
                mPresenter.loadBanner();
                showNormal();
            }
            else {
                showNetErrorToast();
            }
        });

    }

    /**
     * <p>網(wǎng)絡(luò)錯誤的toast提示</p>
     */
    private void showNetErrorToast() {
        ToastUtils.setBgColor(getResources().getColor(R.color.toast_bg_color, null));
        ToastUtils.setMsgColor(getResources().getColor(R.color.toast_text_color, null));
        ToastUtils.showShort(R.string.net_error_toast);
    }

    /**
     * <p>顯示正常內(nèi)容</p>
     */
    private void showNormal() {
        if (mNetErrorLayout != null) {
            mNetErrorLayout.setVisibility(View.GONE);
        }
        mMainBanner.setVisibility(View.VISIBLE);
        mRefreshLayout.setVisibility(View.VISIBLE);
    }

無網(wǎng)絡(luò)時Header和Footer的顯示

在沒有網(wǎng)絡(luò)的情況下懊纳,刷新和加載怎么能成功呢网持,所以需要在刷新和加載的監(jiān)聽中添加處理,核心代碼就是在加載失敗的時候傳入false參數(shù)长踊,框架就會顯示“失敗”了。

refreshLayout.finishRefresh(false);
refreshLayout.finishLoadMore(false);

有網(wǎng)絡(luò)連接萍倡,但是獲取數(shù)據(jù)失敗

無網(wǎng)絡(luò)連接的情況比較好處理身弊,如果連接到了網(wǎng)絡(luò),但是并無法獲取數(shù)據(jù)(比如連接到局域網(wǎng)),就比較惡心了阱佛,因為不知道是什么原因?qū)е碌臄?shù)據(jù)無法獲得帖汞,因此需要進行特殊處理。

自動重連是我能想到的一種處理方法凑术,但是又不能無限重連翩蘸,參考了大神的文章,我的處理方法直接貼代碼淮逊。

    @Override
    public void loadBanner() {

        mModel.loadBanner()
                .retryWhen(throwableObservable -> throwableObservable.flatMap((Function<Throwable,
                        ObservableSource<?>>) throwable -> {

                            LogUtils.d("exception:" + throwable.toString());

                            if (throwable instanceof IOException) {
                                LogUtils.d("IOException need retry");

                                if (mBannerRetryCount < MAX_RETRY_COUNT) {
                                    mBannerRetryCount++;
                                    LogUtils.d("mBannerRetryCount:" + mBannerRetryCount);

                                    int waitRetryTime = 3000 + mBannerRetryCount * 1000;
                                    LogUtils.d("wait time: " + waitRetryTime);

                                    return Observable.just(1).delay(waitRetryTime, TimeUnit.MILLISECONDS);
                                }
                                else {
                                    return Observable.error(new Throwable("retry time reach the max count"));
                                }
                            }
                            else {
                                return Observable.error(new Throwable("not IOException"));
                            }
                        }))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<BannerBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        mCompositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(BannerBean bean) {

                        if (isViewAttached()) {
                            getView().loadBanner(bean);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        LogUtils.d("banner onError()");

                        if (isViewAttached()) {
                            getView().onError(e);
                        }
                    }

                    @Override
                    public void onComplete() {
                        LogUtils.d("banner onComplete()");
                    }
                });
    }

關(guān)鍵代碼就是調(diào)用了retryWhen催首,這里面的處理邏輯就是當異常為IO異常且重連次數(shù)小于最大重試次數(shù)時,進行重連泄鹏,并且每一次重連的等待時間都有所增加郎任。這個邏輯可以根據(jù)自己的實際情況進行修改。

即使采用重連的方法备籽,仍然有可能獲取不到數(shù)據(jù)舶治,這里可以選擇顯示一個類似于“無數(shù)據(jù)”的頁面,也可以不做處理车猬,畢竟還有下拉刷新等可以重新加載數(shù)據(jù)霉猛。最近又開始忙了,后面的內(nèi)容估計要延期了珠闰,下面計劃加動態(tài)網(wǎng)絡(luò)權(quán)限請求惜浅,而不是直接賦予網(wǎng)絡(luò)權(quán)限,因為CTS認證有這個要求铸磅。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赡矢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子阅仔,更是在濱河造成了極大的恐慌吹散,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件八酒,死亡現(xiàn)場離奇詭異空民,居然都是意外死亡,警方通過查閱死者的電腦和手機羞迷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門界轩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人衔瓮,你說我怎么就攤上這事浊猾。” “怎么了热鞍?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵葫慎,是天一觀的道長衔彻。 經(jīng)常有香客問我,道長偷办,這世上最難降的妖魔是什么艰额? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮椒涯,結(jié)果婚禮上柄沮,老公的妹妹穿的比我還像新娘。我一直安慰自己废岂,他們只是感情好祖搓,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著泪喊,像睡著了一般棕硫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上袒啼,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天哈扮,我揣著相機與錄音,去河邊找鬼蚓再。 笑死滑肉,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的摘仅。 我是一名探鬼主播靶庙,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼娃属!你這毒婦竟也來了六荒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤矾端,失蹤者是張志新(化名)和其女友劉穎掏击,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秩铆,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡砚亭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了殴玛。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捅膘。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖滚粟,靈堂內(nèi)的尸體忽然破棺而出寻仗,到底是詐尸還是另有隱情,我是刑警寧澤凡壤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布愧沟,位于F島的核電站蔬咬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏沐寺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一盖奈、第九天 我趴在偏房一處隱蔽的房頂上張望混坞。 院中可真熱鬧,春花似錦钢坦、人聲如沸究孕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厨诸。三九已至,卻和暖如春禾酱,著一層夾襖步出監(jiān)牢的瞬間微酬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工颤陶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留颗管,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓滓走,卻偏偏與公主長得像垦江,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子搅方,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當在唯一索引所對應(yīng)的列上鍵入重復(fù)值時比吭,會觸發(fā)此異常。 O...
    我想起個好名字閱讀 5,321評論 0 9
  • iOS開發(fā)系列--網(wǎng)絡(luò)開發(fā) 概覽 大部分應(yīng)用程序都或多或少會牽扯到網(wǎng)絡(luò)開發(fā)姨涡,例如說新浪微博衩藤、微信等,這些應(yīng)用本身可...
    lichengjin閱讀 3,666評論 2 7
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,105評論 1 32
  • error code(錯誤代碼)=0是操作成功完成绣溜。error code(錯誤代碼)=1是功能錯誤慷彤。error c...
    Heikki_閱讀 3,385評論 1 9
  • error code(錯誤代碼)=2000是無效的像素格式。error code(錯誤代碼)=2001是指定的驅(qū)動...
    Heikki_閱讀 1,800評論 0 4