使用BaseActivity+RxBus+BroadCastReceiver+MVP設(shè)計(jì)模式實(shí)現(xiàn)網(wǎng)絡(luò)狀態(tài)的監(jiān)聽荞估。

MVP最近時(shí)越來越火了,在本Demo中也使用了MVP模式稚新,使得業(yè)務(wù)層和視圖層接口互相抽離勘伺,這樣一來整個(gè)業(yè)務(wù)變得清晰多了,這里我的Activity就是只有一個(gè)業(yè)務(wù)就是發(fā)起HTTP請(qǐng)求褂删,然后他對(duì)應(yīng)的視圖接口就是展示從服務(wù)器上獲得的信息飞醉。
首先我們先來看看MVP的基本Base:
BaseView:


public interface BaseView {

    /**
     * 顯示loading
     */
    void showProgress();
    /**
     * 隱藏loading框
     */
    void hideProgress();
    /**
     * 消息提示
     */
    void toast(String msg);

}

BasePresenter

public abstract class BasePresenter<T> {
    /**
     * 這里可以初始化View接口
     */
    public T view;
     private LifecycleProvider<ActivityEvent>provider;
    /**
     *
     * @param view Activity或者Fragment中的引用this
     */
    public void attach(T view){
        this.view=view;
    }
    public void detach(){
        this.view=null;
    }

    public BasePresenter(LifecycleProvider<ActivityEvent>provider){
        this.provider=provider;
    }


    public LifecycleProvider<ActivityEvent> getProvider() {
        return provider;
    }

    public void setProvider(LifecycleProvider<ActivityEvent> provider) {
        this.provider = provider;
    }

}

MvpActivity

public abstract class MvpActivity<V,P extends BasePresenter<V>> extends BaseActivity {
    protected P presenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        presenter=initPresenter();//實(shí)例化Presenter
        presenter.attach((V) this);//實(shí)例化接口引用
    }

    @Override
    protected void onResume() {
        super.onResume();
        presenter.attach((V) this);//綁定view接口,相當(dāng)于拿到接口的引用
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        presenter.detach();//耗時(shí)操作在這里也結(jié)束
    }
    //實(shí)例化Presenter
    public abstract P initPresenter();
}

BaseActivity

/**
 * 繼承RxAppCompatActivity,內(nèi)部實(shí)現(xiàn)了RxLifeCycle的接口
 */
public class BaseActivity extends RxAppCompatActivity {

    private Observable<MessageEvent> observable;
    private Disposable dp;
    public baseActivityInterface baseActivityInterface;
    //廣播
    private NetChangeReceiver netChangeReceiver;
    @Inject
    MyToast myToast;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        RegistReceiver();
        getRxBus();
    }

    private void RegistReceiver() {
        IntentFilter intentFilter=new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);//網(wǎng)絡(luò)連接過濾器
        netChangeReceiver=new NetChangeReceiver();
        this.registerReceiver(netChangeReceiver,intentFilter);
    }

    private void getRxBus() {

        observable= RxBus.getInstance().toObservable(MessageEvent.class);
        observable.observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<MessageEvent>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        dp=d;
                    }
                    @Override
                    public void onNext(MessageEvent messageEvent) {
                        if(!messageEvent.isConnect()){
                            //斷開網(wǎng)絡(luò)提示信息
                            myToast.showToast(BaseActivity.this,messageEvent.getNetStateMessage());
                        }
                        else if(!messageEvent.isLastConnect()&&messageEvent.isConnect()){
                            baseActivityInterface.reConnect();//重新發(fā)起http請(qǐng)求
                        }
                    }
                    @Override
                    public void onError(Throwable e) {

                    }
                    @Override
                    public void onComplete() {

                    }
                });
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        RxBus.getInstance().unregister(dp);//取消訂閱
        this.unregisterReceiver(netChangeReceiver);//取消廣播接收器
    }
}

我們看到屯阀,再網(wǎng)絡(luò)斷開然后再重新連接的時(shí)候我們調(diào)用了baseActivityInterface reConnect接口缅帘。接下來可以簡(jiǎn)單看看baseActivityInterface,其實(shí)還可以繼續(xù)添加其他的操作在里面。

public interface baseActivityInterface {

    void reConnect();

}

然后看看我們的網(wǎng)絡(luò)狀態(tài)監(jiān)聽廣播:

public class NetChangeReceiver extends BroadcastReceiver {
    private String netStateMessage="";
    private boolean isConnect=false;
    private boolean LastConnect=true;
    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager connectivityManager=(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo();
        if(networkInfo!=null&&networkInfo.isAvailable()){
            switch (networkInfo.getType()){
                case ConnectivityManager.TYPE_WIFI:
                    netStateMessage="正在使用Wifi上網(wǎng)";
                    isConnect=true;
                    //發(fā)送
                    RxBus.getInstance().post(new MessageEvent(netStateMessage,LastConnect,isConnect));//發(fā)送消息
                    LastConnect=isConnect;//如果初始化為true
                    break;
                case ConnectivityManager.TYPE_MOBILE:
                    netStateMessage="正在使用2G/3G/4G網(wǎng)絡(luò)";
                    isConnect=true;
                    //發(fā)送
                    RxBus.getInstance().post(new MessageEvent(netStateMessage,LastConnect,isConnect));//發(fā)送消息
                    LastConnect=isConnect;//如果初始化為true
                    break;
                    default:
                        break;
            }
        }else {
            netStateMessage="當(dāng)前無網(wǎng)絡(luò)連接";
            isConnect=false;
            //發(fā)送
            RxBus.getInstance().post(new MessageEvent(netStateMessage,LastConnect,isConnect));//發(fā)送消息
            LastConnect=isConnect;//如果初始化為true
        }
    }
}

這里簡(jiǎn)單記錄了一下網(wǎng)絡(luò)狀態(tài)變化之前的狀態(tài)
當(dāng)LastConnect=false,isConnect=true表示我們需要重新發(fā)起請(qǐng)求难衰。
然后看看NetWorkPresenter

public class NetWorkPresenter extends BasePresenter<NetWorkView>{

    public NetWorkPresenter(LifecycleProvider<ActivityEvent> provider) {
        super(provider);
    }
    public void getData(PageParmForm pageParmForm, Context mContext){
        new NetRepository().getApplication(pageParmForm)
                 .compose(getProvider().<UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>>>bindUntilEvent(ActivityEvent.DESTROY)
                .subscribe(new BaseObserver<UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>>>(mContext) {
                    @Override
                    public void onError(ExceptionHandle.ResponseException exception) {
                        view.toast(exception.getMessage());
                    }

                    @Override
                    public void onNext(UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>> Response) {
                        view.showApplicationList(Response);
                    }
                });
    }
}

可以看到當(dāng)成功請(qǐng)求后直接交給View層進(jìn)行展示钦无。這里的View其實(shí)就是NetWorkView類型,因?yàn)闄?quán)限為public因此我們可以直接拿到他盖袭。

public interface NetWorkView extends BaseView{
    //顯示從網(wǎng)絡(luò)獲取過來的信息
    void showApplicationList(UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>> Response);
}

然后最后看看Activity中的操作與程序結(jié)構(gòu)失暂。

public class NetWorkActivity extends MvpActivity<NetWorkView,NetWorkPresenter> implements baseActivityInterface,NetWorkView {
      private RecyclerView mRecyclerView;
      private String code;
      private List<UserguideSoftConfig>data=new ArrayList<>();
      private ToolBarView toolBarView;
      private CompositeDisposable compositeDisposable=new CompositeDisposable();
    @Inject
    GenerateAdapter generateAdapter;
    @Inject
    MyToast myToast;
    @Inject
    ActivityOperate activityOperate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_net_work);
        baseActivityInterface =this;//拿到引用
        initView();
        inject();
        Events();
        initAdapter();
        Config();
    }
//啟動(dòng)業(yè)務(wù)調(diào)用
    private void Events() {
        presenter.getData(new PageParmForm(Constant.orderStr,Constant.pageNum,Constant.pageSize),NetWorkActivity.this);
    }


    private void inject() {
        DaggercommonComponent.builder()
                .appComponent(MyApp.getMyApp().getAppComponent())
                .commonModule(new commonModule())
                .build()
                .inject(this);
    }

    public void Config(){
        toolBarView.setNavigationTip(Constant.Toolbar_Title);
    }
    public void initData(){
        new NetRepository().getApplication(new PageParmForm(Constant.orderStr,Constant.pageNum,Constant.pageSize))
        .compose(this.<UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>>>bindUntilEvent(ActivityEvent.DESTROY))//指定訂閱再destroy的時(shí)候呢彼宠,取消訂閱
        .subscribe(new BaseObserver<UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>>>(NetWorkActivity.this) {
            @Override
            public void onError(ExceptionHandle.ResponseException exception) {
                myToast.showToast(NetWorkActivity.this,exception.getMessage());

            }
            @Override
            public void onNext(UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>> Response) {
                data=Response.getData().getList();
                code=Response.getCode();
                generateAdapter.setData(data);
                generateAdapter.notifyDataSetChanged();
            }
        });
    }
    public void initAdapter(){
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
        gridLayoutManager.setOrientation(GridLayoutManager.VERTICAL);
        generateAdapter.setData(data);
        generateAdapter.notifyDataSetChanged();//更新數(shù)據(jù)
        mRecyclerView.setAdapter(generateAdapter);
        mRecyclerView.setLayoutManager(gridLayoutManager);
        //設(shè)置監(jiān)聽事件
        mRecyclerView.addOnItemTouchListener(new RecyclerViewClickListener(NetWorkActivity.this, mRecyclerView, new RecyclerViewClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position, View ItemView) {
                Constant.url=data.get(position).getDetailUrl();
                generateAdapter.notifyItemChanged(position);//刷新點(diǎn)擊事件,展示selector
                activityOperate.LunchActivity(NetWorkActivity.this,WebActivity.class);
            }
            @Override
            public void onItemLongClick(View view, int position, View ItemView) {

            }
        }));
    }
    public void initView(){
        mRecyclerView = findViewById(R.id.mRecyclerView);
        toolBarView=findViewById(R.id.toolBarView);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(compositeDisposable!=null&&!compositeDisposable.isDisposed()){
            compositeDisposable.dispose();//取消訂閱
        }
    }

    @Override
    public NetWorkPresenter initPresenter() {
        return new NetWorkPresenter(this);
    }

    @Override
    public void reConnect() {
        myToast.showToast(NetWorkActivity.this,"已經(jīng)開始重新連接!!");
        initData();
    }

    @Override
    public void showApplicationList(UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>> Response) {
        data=Response.getData().getList();
        generateAdapter.setData(data);
        generateAdapter.notifyDataSetChanged();//更新數(shù)據(jù)
    }
    @Override
    public void showProgress() {

    }
    @Override
    public void hideProgress() {

    }
    @Override
    public void toast(String msg) {
        myToast.showToast(NetWorkActivity.this,msg);
    }
}

這里我們直接用Presenter去實(shí)現(xiàn)業(yè)務(wù)弟塞,緊接著View層展示凭峡,可以看到我們不僅實(shí)現(xiàn)了View層,還實(shí)現(xiàn)了baseActivityInterface决记,這里主要時(shí)想把重新連接服務(wù)器的請(qǐng)求寫在這里摧冀。
好了整個(gè)Demo是先了用MVP的方式處理業(yè)務(wù),還包括監(jiān)聽網(wǎng)絡(luò)狀態(tài)系宫,網(wǎng)絡(luò)恢復(fù)后重新發(fā)起請(qǐng)求等功能索昂,這里我們是結(jié)合廣播與RxBus來實(shí)現(xiàn)的。當(dāng)然不喜歡盡情拍磚笙瑟。

最后附上RxBus:

public class RxBus {
    private static volatile RxBus instance;
    private final Relay<Object> mBus;

    public RxBus() {
        this.mBus = PublishRelay.create().toSerialized();
    }

    public static RxBus getInstance() {
        if (instance == null) {
            synchronized (RxBus.class) {
                if (instance == null) {
                    instance = Holder.BUS;
                }
            }
        }
        return instance;
    }
    public void post(Object obj) {
        mBus.accept(obj);
    }

    public <T> Observable<T> toObservable(Class<T> tClass) {
        return  mBus.ofType(tClass);
    }

    public Observable<Object> toObservable() {
        return mBus;
    }

    public boolean hasObservers() {
        return mBus.hasObservers();
    }

    private static class Holder {
        private static final RxBus BUS = new RxBus();
    }

    public void unregister(Disposable disposable) {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }
}

MessageEvent:

public class MessageEvent {

    String netStateMessage;
    boolean lastConnect=true;
    boolean isConnect;

    public boolean isLastConnect() {
        return lastConnect;
    }

    public void setLastConnect(boolean lastConnect) { this.lastConnect = lastConnect; }

    public boolean isConnect() {
        return isConnect;
    }

    public void setConnect(boolean connect) {
        isConnect = connect;
    }


    public MessageEvent(String netStateMessage,boolean lastConnect,boolean isConnect) {
        this.netStateMessage = netStateMessage;
        this.lastConnect=lastConnect;
        this.isConnect=isConnect;
    }

    public String getNetStateMessage() {
        return netStateMessage;
    }

    public void setNetStateMessage(String netStateMessage) {
        this.netStateMessage = netStateMessage; }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末楼镐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子往枷,更是在濱河造成了極大的恐慌,老刑警劉巖凄杯,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件错洁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡戒突,警方通過查閱死者的電腦和手機(jī)屯碴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膊存,“玉大人导而,你說我怎么就攤上這事「羝椋” “怎么了今艺?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)爵卒。 經(jīng)常有香客問我虚缎,道長(zhǎng),這世上最難降的妖魔是什么钓株? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任实牡,我火速辦了婚禮,結(jié)果婚禮上轴合,老公的妹妹穿的比我還像新娘创坞。我一直安慰自己,他們只是感情好受葛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布题涨。 她就那樣靜靜地躺著偎谁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪携栋。 梳的紋絲不亂的頭發(fā)上搭盾,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音婉支,去河邊找鬼鸯隅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛向挖,可吹牛的內(nèi)容都是我干的蝌以。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼何之,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼跟畅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起溶推,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤徊件,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蒜危,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虱痕,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年辐赞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了部翘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡响委,死狀恐怖新思,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赘风,我是刑警寧澤夹囚,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站贝次,受9級(jí)特大地震影響崔兴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蛔翅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一敲茄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧山析,春花似錦堰燎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赊淑。三九已至,卻和暖如春仅讽,著一層夾襖步出監(jiān)牢的瞬間陶缺,已是汗流浹背杏糙。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工夯到, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人载慈。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓徽千,卻偏偏與公主長(zhǎng)得像苫费,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子双抽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

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