zoukankan      html  css  js  c++  java
  • MVP+Retrofit+RxJava

    添加依赖

    ext {
        appcompatVersion = '27.1.0'
        butterknifeVersion = '8.4.0'
        retrofitVersion = '2.3.0'
        logginginterceptor = '3.9.1'
        rxjavaVersion = '2.1.11'
        rxandroidVersion = "2.0.2"
    }
        implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
        implementation "com.squareup.okhttp3:logging-interceptor:$logginginterceptor"
        implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion"
        implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofitVersion"
        implementation "io.reactivex.rxjava2:rxandroid:$rxandroidVersion"
        implementation "io.reactivex.rxjava2:rxjava:$rxjavaVersion"
    import okhttp3.OkHttpClient;
    import okhttp3.logging.HttpLoggingInterceptor;
    import retrofit2.Retrofit;
    import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
    import retrofit2.converter.gson.GsonConverterFactory;
    
    
    public class ApiClient {
        public static Retrofit mRetrofit;
    
        public static Retrofit retrofit() {
            if (mRetrofit == null) {
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
    
    
                // Log信息拦截器
                HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
                loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
                //设置 Debug Log 模式
                builder.addInterceptor(loggingInterceptor);
    
                OkHttpClient okHttpClient = builder.build();
                mRetrofit = new Retrofit.Builder()
                        .baseUrl(ApiStores.API_SERVER_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        .client(okHttpClient)
                        .build();
            }
            return mRetrofit;
        }
    
    }
    import com.loaderman.jsoupdemo.main.MainModel;
    
    import io.reactivex.Observable;
    import retrofit2.Call;
    import retrofit2.http.GET;
    import retrofit2.http.Path;
    
    
    public interface ApiStores {
        //baseUrl
        String API_SERVER_URL = "http://www.weather.com.cn/";
    
        //加载天气
        @GET("adat/sk/{cityId}.html")
        Call<MainModel> loadDataByRetrofit(@Path("cityId") String cityId);
    
        //加载天气
        @GET("adat/sk/{cityId}.html")
        Observable<MainModel> loadDataByRetrofitRxJava(@Path("cityId") String cityId);
    }
    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Response;
    
    public abstract class RetrofitCallback<M> implements Callback<M> {
    
        public abstract void onSuccess(M model);
        public abstract void onFailure(int code, String msg);
        public abstract void onThrowable(Throwable t);
        public abstract void onFinish();
        @Override
        public void onResponse(Call<M> call, Response<M> response) {
            if (response.isSuccessful()) {
                onSuccess(response.body());
            } else {
                onFailure(response.code(), response.errorBody().toString());
            }
            onFinish();
        }
    
        @Override
        public void onFailure(Call<M> call, Throwable t) {
            onThrowable(t);
            onFinish();
        }
    }
    import io.reactivex.observers.DisposableObserver;
    import retrofit2.HttpException;
    
    public abstract class ApiCallback<M> extends DisposableObserver<M> {
    
        public abstract void onSuccess(M model);
    
        public abstract void onFailure(String msg);
    
        public abstract void onFinish();
    
    
        @Override
        public void onError(Throwable e) {
            e.printStackTrace();
            if (e instanceof HttpException) {
                HttpException httpException = (HttpException) e;
                //httpException.response().errorBody().string()
                int code = httpException.code();
                String msg = httpException.getMessage();
                if (code == 504) {
                    msg = "网络不给力";
                }
                if (code == 502 || code == 404) {
                    msg = "服务器异常,请稍后再试";
                }
                onFailure(msg);
            } else {
                onFailure(e.getMessage());
            }
            onFinish();
        }
    
        @Override
        public void onNext(M model) {
            onSuccess(model);
    
        }
    
        @Override
        public void onComplete() {
            onFinish();
        }
    }
    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.support.annotation.LayoutRes;
    import android.support.v7.app.ActionBar;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.loaderman.jsoupdemo.R;
    import com.loaderman.jsoupdemo.retrofit.ApiClient;
    import com.loaderman.jsoupdemo.retrofit.ApiStores;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import io.reactivex.Observable;
    import io.reactivex.android.schedulers.AndroidSchedulers;
    import io.reactivex.disposables.CompositeDisposable;
    import io.reactivex.disposables.Disposable;
    import io.reactivex.observers.DisposableObserver;
    import io.reactivex.schedulers.Schedulers;
    import retrofit2.Call;
    
    
    public abstract class BaseActivity extends AppCompatActivity {
        public Activity mActivity;
        private CompositeDisposable mCompositeDisposable;
        private List<Call> calls;
    
        @Override
        public void setContentView(@LayoutRes int layoutResID) {
            super.setContentView(layoutResID);
            mActivity = this;
        }
    
    
        @Override
        public void setContentView(View view) {
            super.setContentView(view);
            mActivity = this;
        }
    
        @Override
        public void setContentView(View view, ViewGroup.LayoutParams params) {
            super.setContentView(view, params);
            mActivity = this;
        }
    
    
        @Override
        protected void onDestroy() {
            callCancel();
            onUnsubscribe();
            super.onDestroy();
        }
    
        public ApiStores apiStores() {
            return ApiClient.retrofit().create(ApiStores.class);
        }
    
        public void addCalls(Call call) {
            if (calls == null) {
                calls = new ArrayList<>();
            }
            calls.add(call);
        }
    
        private void callCancel() {
            if (calls != null && calls.size() > 0) {
                for (Call call : calls) {
                    if (!call.isCanceled())
                        call.cancel();
                }
                calls.clear();
            }
        }
    
    
        public <T> void addSubscription(Observable<T> observable, DisposableObserver<T> observer) {
            if (mCompositeDisposable == null) {
                mCompositeDisposable = new CompositeDisposable();
            }
            mCompositeDisposable.add(observer);
    
            observable.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(observer);
        }
    
        public void addSubscription(Disposable disposable) {
            if (mCompositeDisposable == null) {
                mCompositeDisposable = new CompositeDisposable();
            }
            mCompositeDisposable.add(disposable);
        }
    
        public void onUnsubscribe() {
    
            //取消注册,以避免内存泄露
            if (mCompositeDisposable != null)
                mCompositeDisposable.dispose();
        }
    
        public Toolbar initToolBar(String title) {
    
            Toolbar toolbar = findViewById(R.id.toolbar);
            if (toolbar != null) {
                setSupportActionBar(toolbar);
                TextView toolbaTitle = toolbar.findViewById(R.id.toolbar_title);
                toolbaTitle.setText(title);
            }
            ActionBar actionBar = getSupportActionBar();
            if (actionBar != null) {
                actionBar.setDisplayHomeAsUpEnabled(true);
                actionBar.setDisplayShowTitleEnabled(false);
            }
            return toolbar;
        }
    
        public Toolbar initToolBarAsHome(String title) {
    
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            if (toolbar != null) {
                setSupportActionBar(toolbar);
                TextView toolbaTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
                toolbaTitle.setText(title);
            }
            ActionBar actionBar = getSupportActionBar();
            if (actionBar != null) {
                actionBar.setDisplayHomeAsUpEnabled(false);
                actionBar.setDisplayShowTitleEnabled(false);
            }
            return toolbar;
        }
    
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
    
                case android.R.id.home:
                    super.onBackPressed();//返回
                    return true;
                default:
                    return super.onOptionsItemSelected(item);
            }
    
        }
    
        public void toastShow(int resId) {
            Toast.makeText(mActivity, resId, Toast.LENGTH_SHORT).show();
        }
    
        public void toastShow(String resId) {
            Toast.makeText(mActivity, resId, Toast.LENGTH_SHORT).show();
        }
    
        public ProgressDialog progressDialog;
    
        public ProgressDialog showProgressDialog() {
            progressDialog = new ProgressDialog(mActivity);
            progressDialog.setMessage("加载中");
            progressDialog.show();
            return progressDialog;
        }
    
        public ProgressDialog showProgressDialog(CharSequence message) {
            progressDialog = new ProgressDialog(mActivity);
            progressDialog.setMessage(message);
            progressDialog.show();
            return progressDialog;
        }
    
        public void dismissProgressDialog() {
            if (progressDialog != null && progressDialog.isShowing()) {
                // progressDialog.hide();会导致android.view.WindowLeaked
                progressDialog.dismiss();
            }
        }
    
    }
    import android.app.Activity;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v7.widget.Toolbar;
    import android.view.View;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.loaderman.jsoupdemo.R;
    
    import io.reactivex.disposables.CompositeDisposable;
    import io.reactivex.observers.DisposableObserver;
    
    
    public class BaseFragment extends Fragment {
        public Activity mActivity;
    
    
        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            mActivity = getActivity();
        }
    
        public Toolbar initToolBar(View view, String title) {
            Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
            TextView toolbar_title = (TextView) toolbar.findViewById(R.id.toolbar_title);
            toolbar_title.setText(title);
            return toolbar;
        }
    
    
        public void toastShow(int resId) {
            Toast.makeText(mActivity, resId, Toast.LENGTH_SHORT).show();
        }
    
        public void toastShow(String resId) {
            Toast.makeText(mActivity, resId, Toast.LENGTH_SHORT).show();
        }
    
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            onUnsubscribe();
        }
    
        private CompositeDisposable mCompositeDisposable;
    
        public void onUnsubscribe() {
            //取消注册,以避免内存泄露
            if (mCompositeDisposable != null) {
                mCompositeDisposable.dispose();
            }
        }
    
        public void addSubscription(DisposableObserver observer) {
    //        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
    //        }
            mCompositeDisposable.add(observer);
        }
    }
    public interface BaseView {
        void showLoading();
    
        void hideLoading();
    }
    public class MainModel {
    
        private WeatherinfoBean weatherinfo;
    
        public WeatherinfoBean getWeatherinfo() {
            return weatherinfo;
        }
    
        public void setWeatherinfo(WeatherinfoBean weatherinfo) {
            this.weatherinfo = weatherinfo;
        }
    
        public static class WeatherinfoBean {
            private String city;
            private String cityid;
            private String temp;
            private String WD;
            private String WS;
            private String SD;
            private String WSE;
            private String time;
            private String isRadar;
            private String Radar;
            private String njd;
            private String qy;
    
            public String getCity() {
                return city;
            }
    
            public void setCity(String city) {
                this.city = city;
            }
    
            public String getCityid() {
                return cityid;
            }
    
            public void setCityid(String cityid) {
                this.cityid = cityid;
            }
    
            public String getTemp() {
                return temp;
            }
    
            public void setTemp(String temp) {
                this.temp = temp;
            }
    
            public String getWD() {
                return WD;
            }
    
            public void setWD(String WD) {
                this.WD = WD;
            }
    
            public String getWS() {
                return WS;
            }
    
            public void setWS(String WS) {
                this.WS = WS;
            }
    
            public String getSD() {
                return SD;
            }
    
            public void setSD(String SD) {
                this.SD = SD;
            }
    
            public String getWSE() {
                return WSE;
            }
    
            public void setWSE(String WSE) {
                this.WSE = WSE;
            }
    
            public String getTime() {
                return time;
            }
    
            public void setTime(String time) {
                this.time = time;
            }
    
            public String getIsRadar() {
                return isRadar;
            }
    
            public void setIsRadar(String isRadar) {
                this.isRadar = isRadar;
            }
    
            public String getRadar() {
                return Radar;
            }
    
            public void setRadar(String Radar) {
                this.Radar = Radar;
            }
    
            public String getNjd() {
                return njd;
            }
    
            public void setNjd(String njd) {
                this.njd = njd;
            }
    
            public String getQy() {
                return qy;
            }
    
            public void setQy(String qy) {
                this.qy = qy;
            }
        }
    }
    import com.loaderman.jsoupdemo.other.BasePresenter;
    import com.loaderman.jsoupdemo.retrofit.ApiCallback;
    
    
    public class MainPresenter extends BasePresenter<MainView> {
    
        public MainPresenter(MainView view) {
            attachView(view);
        }
    
        public void loadDataByRetrofitRxjava(String cityId) {
            mvpView.showLoading();
            addSubscription(apiStores.loadDataByRetrofitRxJava(cityId),
                    new ApiCallback<MainModel>() {
                        @Override
                        public void onSuccess(MainModel model) {
                            mvpView.getDataSuccess(model);
                        }
    
                        @Override
                        public void onFailure(String msg) {
                            mvpView.getDataFail(msg);
                        }
    
    
                        @Override
                        public void onFinish() {
                            mvpView.hideLoading();
                        }
    
                    });
        }
    
    }
    public interface MainView extends BaseView {
    
        void getDataSuccess(MainModel model);
    
        void getDataFail(String msg);
    
    }
    import com.loaderman.jsoupdemo.retrofit.ApiClient;
    import com.loaderman.jsoupdemo.retrofit.ApiStores;
    
    import io.reactivex.Observable;
    import io.reactivex.android.schedulers.AndroidSchedulers;
    import io.reactivex.disposables.CompositeDisposable;
    import io.reactivex.observers.DisposableObserver;
    import io.reactivex.schedulers.Schedulers;
    
    
    public class BasePresenter<V> {
        public V mvpView;
        protected ApiStores apiStores;
        private CompositeDisposable mCompositeDisposable;
    
        public void attachView(V mvpView) {
            this.mvpView = mvpView;
            apiStores = ApiClient.retrofit().create(ApiStores.class);
        }
    
    
        public void detachView() {
            this.mvpView = null;
            onUnSubscribe();
        }
    
    
        //RxJava取消注册,以避免内存泄露
        public void onUnSubscribe() {
            if (mCompositeDisposable != null) {
                mCompositeDisposable.dispose();
            }
        }
    
    
        public void addSubscription(Observable observable, DisposableObserver observer) {
            if (mCompositeDisposable == null) {
                mCompositeDisposable = new CompositeDisposable();
            }
    
            mCompositeDisposable.add(observer);
    
            observable.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeWith(observer);
        }
    }
    import android.os.Bundle;
    
    import com.loaderman.jsoupdemo.base.BaseActivity;
    
    
    public abstract class MvpActivity<P extends BasePresenter> extends BaseActivity {
        protected P mvpPresenter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            mvpPresenter = createPresenter();
            super.onCreate(savedInstanceState);
        }
    
        protected abstract P createPresenter();
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (mvpPresenter != null) {
                mvpPresenter.detachView();
            }
        }
    
        public void showLoading() {
            showProgressDialog();
        }
    
        public void hideLoading() {
            dismissProgressDialog();
        }
    }
    import android.os.Bundle;
    import android.view.View;
    
    import com.loaderman.jsoupdemo.base.BaseFragment;
    
    public abstract class MvpFragment<P extends BasePresenter> extends BaseFragment {
        protected P mvpPresenter;
    
        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            mvpPresenter = createPresenter();
        }
    
        protected abstract P createPresenter();
    
    
        @Override
        public void onDestroyView() {
            super.onDestroyView();
            if (mvpPresenter != null) {
                mvpPresenter.detachView();
            }
        }
    }
    import android.os.Bundle;
    import android.view.View;
    import android.widget.TextView;
    
    import com.loaderman.jsoupdemo.R;
    import com.loaderman.jsoupdemo.main.MainModel;
    import com.loaderman.jsoupdemo.main.MainPresenter;
    import com.loaderman.jsoupdemo.main.MainView;
    import com.loaderman.jsoupdemo.other.MvpActivity;
    import com.loaderman.jsoupdemo.retrofit.ApiCallback;
    import com.loaderman.jsoupdemo.retrofit.RetrofitCallback;
    
    import retrofit2.Call;
    
    
    public class MainActivity extends MvpActivity<MainPresenter> implements MainView {
    
        private TextView text;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            text = findViewById(R.id.text);
            initToolBarAsHome(getString(R.string.title));
        }
    
        @Override
        protected MainPresenter createPresenter() {
            return new MainPresenter(this);
        }
    
    
        @Override
        public void getDataSuccess(MainModel model) {
            //接口成功回调
            dataSuccess(model);
        }
    
        @Override
        public void getDataFail(String msg) {
            toastShow(getString(R.string.net_error));
    
        }
    
    
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.button0://Retrofit常规用法
                    loadDataByRetrofit();
                    break;
                case R.id.button1://RxJava+Retrofit常规用法
                    loadDataByRetrofitRxJava();
                    break;
                case R.id.button2://mvp+RxJava+Retrofit常规用法
                    //请求接口
                    mvpPresenter.loadDataByRetrofitRxjava("101310222");
                    break;
            }
        }
    
        private void loadDataByRetrofit() {
            showProgressDialog();
            Call<MainModel> call = apiStores().loadDataByRetrofit("101190201");
            call.enqueue(new RetrofitCallback<MainModel>() {
                @Override
                public void onSuccess(MainModel model) {
                    dataSuccess(model);
                }
    
                @Override
                public void onFailure(int code, String msg) {
                    toastShow(msg);
                }
    
                @Override
                public void onThrowable(Throwable t) {
                    toastShow(t.getMessage());
                }
    
                @Override
                public void onFinish() {
                    dismissProgressDialog();
                }
            });
            addCalls(call);
        }
    
        //全国+国外主要城市代码http://mobile.weather.com.cn/js/citylist.xml
        private void loadDataByRetrofitRxJava() {
            showProgressDialog();
            addSubscription(
                    apiStores().loadDataByRetrofitRxJava("101220602"),
                    new ApiCallback<MainModel>() {
    
                        @Override
                        public void onSuccess(MainModel model) {
                            dataSuccess(model);
                        }
    
                        @Override
                        public void onFailure(String msg) {
                            toastShow(msg);
                        }
    
                        @Override
                        public void onFinish() {
                            dismissProgressDialog();
                        }
                    });
        }
    
        private void dataSuccess(MainModel model) {
            MainModel.WeatherinfoBean weatherinfo = model.getWeatherinfo();
            String showData = getResources().getString(R.string.city) + weatherinfo.getCity()
                    + getResources().getString(R.string.wd) + weatherinfo.getWD()
                    + getResources().getString(R.string.ws) + weatherinfo.getWS()
                    + getResources().getString(R.string.time) + weatherinfo.getTime();
            text.setText(showData);
        }
    }

    main布局

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".ui.MainActivity">
    
        <include layout="@layout/toolbar" />
    
        <Button
            android:id="@+id/button0"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="20dp"
            android:onClick="onClick"
            android:text="@string/text0" />
    
        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="20dp"
            android:onClick="onClick"
            android:text="@string/text1" />
    
        <Button
            android:id="@+id/button2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="20dp"
            android:onClick="onClick"
            android:text="@string/text2" />
    
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp" />
    
    </LinearLayout>

    toolbar布局

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?colorPrimary"
        android:minHeight="?actionBarSize">
    
        <TextView
            android:id="@+id/toolbar_title"
            style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:textColor="@android:color/white"
            android:textStyle="bold"/>
    </android.support.v7.widget.Toolbar>

    String

    <resources>
        <string name="app_name">天气</string>
        <string name="hello_world">Hello world!</string>
        <string name="action_settings">Settings</string>
        <string name="city">城市:</string>
        <string name="wd">
    风向:</string>
        <string name="ws">
    风级:</string>
        <string name="time">
    发布时间:</string>
        <string name="net_error">网络不给力</string>
        <string name="title">MVP+Retrofit+Rxjava2</string>
        <string name="text0">普通写法(Retrofit)</string>
        <string name="text1">普通写法(Retrofit+Rxjava)</string>
        <string name="text2">MVP+Retrofit+Rxjava</string>
    </resources>

    最后添加网络权限

        <uses-permission android:name="android.permission.INTERNET" />

    运行即可

  • 相关阅读:
    Linux之网络基础
    Tomcat配置虚拟目录并发布web应用
    Linux之权限管理操作
    Linux之shell编程基础
    Python简介
    Python代码注释 Python零基础入门教程
    Python Pycharm Anacanda 区别
    Python Hello World入门
    Python2.x 和 Python3.x,如何选择?
    数据库课程设计心得【1】
  • 原文地址:https://www.cnblogs.com/loaderman/p/10183575.html
Copyright © 2011-2022 走看看