Rxjava+Retrofit+Mvp的使用實例(基於retrofit2.1.0)

Rxjava+Retrofit+Mvp的使用實例(基於retrofit2.1.0) [複製鏈接]

2017-5-25 10:49
一生中所愛 閱讀:551 評論:10 贊:3
Tag:  Android ,mvp ,retrofit ,rxjava

1.MVP介紹

Android項目中,Activity和Fragment佔據了大部分的開發工作。如果有一種設計模式(或者說代碼結構)專門是爲優化Activity和Fragment的代碼而產生的,你說這種模式重要不?這就是MVP設計模式。

按照MVC的分層,Activity和Fragment(後面只說Activity)應該屬於View層,用於展示UI界面,以及接收用戶的輸入,此外還要承擔一些生命週期的工作。Activity是在Android開發中充當非常重要的角色,特別是TA的生命週期的功能,所以開發的時候我們經常把一些業務邏輯直接寫在Activity裏面,這非常直觀方便,代價就是Activity會越來越臃腫,超過1000行代碼是常有的事,而且如果是一些可以通用的業務邏輯(比如用戶登錄),寫在具體的Activity裏就意味着這個邏輯不能複用了。如果有進行代碼重構經驗的人,看到1000+行的類肯定會有所顧慮。因此,Activity不僅承擔了View的角色,還承擔了一部分的Controller角色,這樣一來V和C就耦合在一起了,雖然這樣寫方便,但是如果業務調整的話,要維護起來就難了,而且在一個臃腫的Activity類查找業務邏輯的代碼也會非常蛋疼,所以看起來有必要在Activity中,把View和Controller抽離開來,而這就是MVP模式的工作了。

MVP模式的核心思想:

MVP把Activity中的UI邏輯抽象成View接口,把業務邏輯抽象成Presenter接口,Model類還是原來的Model。

這就是MVP模式,現在這樣的話,Activity的工作的簡單了,只用來響應生命週期,其他工作都丟到Presenter中去完成。從上圖可以看出,Presenter是Model和View之間的橋樑,爲了讓結構變得更加簡單,View並不能直接對Model進行操作,這也是MVP與MVC最大的不同之處。

2.與mvc區別


3.Rxjava+Retrofit+Mvp的在項目中得使用

1)項目結構如下


2)添加依賴

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.0'
    compile 'io.reactivex:rxandroid:1.2.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    testCompile 'junit:junit:4.12'
}

3)api包內容


public interface APIManagerService {
    @GET("/weather/index")
    Observable<WeatherData> getWeatherData(@Query("format") String format, @Query("cityname") String cityname, @Query("key") String key) ;

}

public class APIManager {
    private static final String ENDPOINT = "http://v.juhe.cn";
    private static final Retrofit sRetrofit = new Retrofit .Builder()
            .baseUrl(ENDPOINT)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作爲回調適配器
            .build();

    private static final APIManagerService apiManager = sRetrofit.create(APIManagerService.class);

    /**
     * 獲取天氣數據
     * @param city
     * @return
     */
    public static Observable<WeatherData> getWeatherData(String format, String city) {
        return apiManager.getWeatherData(format,city,"ad1d20bebafe0668502c8eea5ddd0333");
    }

}

4)創建bean對象

public class WeatherData {

    private String resultcode;
    private String reason;
  
    private ResultEntity result;
    private int error_code;

    public void setResultcode(String resultcode) {
        this.resultcode = resultcode;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    public void setResult(ResultEntity result) {
        this.result = result;
    }

    public void setError_code(int error_code) {
        this.error_code = error_code;
    }

    public String getResultcode() {
        return resultcode;
    }

    public String getReason() {
        return reason;
    }

    public ResultEntity getResult() {
        return result;
    }

    public int getError_code() {
        return error_code;
    }

    public static class ResultEntity { 

        private SkEntity sk;
       
        private TodayEntity today;

        private List<FutureEntity> future;

        public void setSk(SkEntity sk) {
            this.sk = sk;
        }

        public void setToday(TodayEntity today) {
            this.today = today;
        }

        public void setFuture(List<FutureEntity> future) {
            this.future = future;
        }

        public SkEntity getSk() {
            return sk;
        }

        public TodayEntity getToday() {
            return today;
        }

        public List<FutureEntity> getFuture() {
            return future;
        }

        public static class SkEntity {
            private String temp;
            private String wind_direction;
            private String wind_strength;
            private String humidity;
            private String time;

            public void setTemp(String temp) {
                this.temp = temp;
            }

            public void setWind_direction(String wind_direction) {
                this.wind_direction = wind_direction;
            }

            public void setWind_strength(String wind_strength) {
                this.wind_strength = wind_strength;
            }

            public void setHumidity(String humidity) {
                this.humidity = humidity;
            }

            public void setTime(String time) {
                this.time = time;
            }

            public String getTemp() {
                return temp;
            }

            public String getWind_direction() {
                return wind_direction;
            }

            public String getWind_strength() {
                return wind_strength;
            }

            public String getHumidity() {
                return humidity;
            }

            public String getTime() {
                return time;
            }

            @Override
            public String toString() {
                return "SkEntity{" +
                        "temp='" + temp + '\'' +
                        ", wind_direction='" + wind_direction + '\'' +
                        ", wind_strength='" + wind_strength + '\'' +
                        ", humidity='" + humidity + '\'' +
                        ", time='" + time + '\'' +
                        '}';
            }
        }

        public static class TodayEntity {

            @Override
            public String toString() {
                return "TodayEntity{" +
                        "temperature='" + temperature + '\'' +
                        ", weather='" + weather + '\'' +
                        ", weather_id=" + weather_id +
                        ", wind='" + wind + '\'' +
                        ", week='" + week + '\'' +
                        ", city='" + city + '\'' +
                        ", date_y='" + date_y + '\'' +
                        ", dressing_index='" + dressing_index + '\'' +
                        ", dressing_advice='" + dressing_advice + '\'' +
                        ", uv_index='" + uv_index + '\'' +
                        ", comfort_index='" + comfort_index + '\'' +
                        ", wash_index='" + wash_index + '\'' +
                        ", travel_index='" + travel_index + '\'' +
                        ", exercise_index='" + exercise_index + '\'' +
                        ", drying_index='" + drying_index + '\'' +
                        '}';
            }

            private String temperature;
            private String weather;
       
            private WeatherIdEntity weather_id;
            private String wind;
            private String week;
            private String city;
            private String date_y;
            private String dressing_index;
            private String dressing_advice;
            private String uv_index;
            private String comfort_index;
            private String wash_index;
            private String travel_index;
            private String exercise_index;
            private String drying_index;

            public void setTemperature(String temperature) {
                this.temperature = temperature;
            }

            public void setWeather(String weather) {
                this.weather = weather;
            }

            public void setWeather_id(WeatherIdEntity weather_id) {
                this.weather_id = weather_id;
            }

            public void setWind(String wind) {
                this.wind = wind;
            }

            public void setWeek(String week) {
                this.week = week;
            }

            public void setCity(String city) {
                this.city = city;
            }

            public void setDate_y(String date_y) {
                this.date_y = date_y;
            }

            public void setDressing_index(String dressing_index) {
                this.dressing_index = dressing_index;
            }

            public void setDressing_advice(String dressing_advice) {
                this.dressing_advice = dressing_advice;
            }

            public void setUv_index(String uv_index) {
                this.uv_index = uv_index;
            }

            public void setComfort_index(String comfort_index) {
                this.comfort_index = comfort_index;
            }

            public void setWash_index(String wash_index) {
                this.wash_index = wash_index;
            }

            public void setTravel_index(String travel_index) {
                this.travel_index = travel_index;
            }

            public void setExercise_index(String exercise_index) {
                this.exercise_index = exercise_index;
            }

            public void setDrying_index(String drying_index) {
                this.drying_index = drying_index;
            }

            public String getTemperature() {
                return temperature;
            }

            public String getWeather() {
                return weather;
            }

            public WeatherIdEntity getWeather_id() {
                return weather_id;
            }

            public String getWind() {
                return wind;
            }

            public String getWeek() {
                return week;
            }

            public String getCity() {
                return city;
            }

            public String getDate_y() {
                return date_y;
            }

            public String getDressing_index() {
                return dressing_index;
            }

            public String getDressing_advice() {
                return dressing_advice;
            }

            public String getUv_index() {
                return uv_index;
            }

            public String getComfort_index() {
                return comfort_index;
            }

            public String getWash_index() {
                return wash_index;
            }

            public String getTravel_index() {
                return travel_index;
            }

            public String getExercise_index() {
                return exercise_index;
            }

            public String getDrying_index() {
                return drying_index;
            }

            public static class WeatherIdEntity {
                private String fa;
                private String fb;

                public void setFa(String fa) {
                    this.fa = fa;
                }

                public void setFb(String fb) {
                    this.fb = fb;
                }

                public String getFa() {
                    return fa;
                }

                public String getFb() {
                    return fb;
                }
            }
        }

        public static class FutureEntity {
            private String temperature;
            private String weather;
            /**
             * fa : 01
             * fb : 01
             */

            private WeatherIdEntity weather_id;
            private String wind;
            private String week;
            private String date;

            public void setTemperature(String temperature) {
                this.temperature = temperature;
            }

            public void setWeather(String weather) {
                this.weather = weather;
            }

            public void setWeather_id(WeatherIdEntity weather_id) {
                this.weather_id = weather_id;
            }

            public void setWind(String wind) {
                this.wind = wind;
            }

            public void setWeek(String week) {
                this.week = week;
            }

            public void setDate(String date) {
                this.date = date;
            }

            public String getTemperature() {
                return temperature;
            }

            public String getWeather() {
                return weather;
            }

            public WeatherIdEntity getWeather_id() {
                return weather_id;
            }

            public String getWind() {
                return wind;
            }

            public String getWeek() {
                return week;
            }

            public String getDate() {
                return date;
            }


            public static class WeatherIdEntity {
                private String fa;
                private String fb;

                public void setFa(String fa) {
                    this.fa = fa;
                }

                public void setFb(String fb) {
                    this.fb = fb;
                }

                public String getFa() {
                    return fa;
                }

                public String getFb() {
                    return fb;
                }

                @Override
                public String toString() {
                    return "WeatherIdEntity{" +
                            "fa='" + fa + '\'' +
                            ", fb='" + fb + '\'' +
                            '}';
                }
            }

            @Override
            public String toString() {
                return "FutureEntity{" +
                        "temperature='" + temperature + '\'' +
                        ", weather='" + weather + '\'' +
                        ", weather_id=" + weather_id +
                        ", wind='" + wind + '\'' +
                        ", week='" + week + '\'' +
                        ", date='" + date + '\'' +
                        '}';
            }
        }

        @Override
        public String toString() {
            return "ResultEntity{" +
                    "sk=" + sk +
                    ", today=" + today +
                    ", future=" + future +
                    '}';
        }
    }

    @Override
    public String toString() {
        return "WeatherData{" +
                "resultcode='" + resultcode + '\'' +
                ", reason='" + reason + '\'' +
                ", result=" + result +
                ", error_code=" + error_code +
                '}';
    }

5)model層

public interface WeatherModel {
    Subscription getWeatherData(String format, String city);
}
public class WeatherModelImp implements WeatherModel {

    private WeatherOnListener mWeatherOnListener;
    public WeatherModelImp(WeatherOnListener mWeatherOnListener) {
        this.mWeatherOnListener = mWeatherOnListener;
    }

    @Override
    public Subscription getWeatherData(String format, String city) {
        //com.example.admin.rxretrofitmvp.api.APIManager
        Observable<WeatherData> request = com.example.admin.rxretrofitmvp.api.APIManager.getWeatherData(format, city).cache();

           Subscription sub = request.subscribeOn(Schedulers.io())
                  .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Action1<WeatherData>() {
                        @Override
                        public void call(WeatherData weatherData) {
                            mWeatherOnListener.onSuccess(weatherData);
                        }
                    }, new Action1<Throwable>() {
                        @Override
                        public void call(Throwable throwable) {
                           mWeatherOnListener.onFailure(throwable);
                       }
                   });
           return sub;
    }

6)Present層

public class BasePesenter {
    protected CompositeSubscription mCompositeSubscription;

    //RXjava取消註冊,以避免內存泄露
    public void onUnsubscribe() {
        if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
            mCompositeSubscription.unsubscribe();
        }
    }

    //RXjava註冊
    public void addSubscription(Subscription subscriber) {
        if (mCompositeSubscription == null) {
            mCompositeSubscription = new CompositeSubscription();
        }
        mCompositeSubscription.add(subscriber);
    }
}

public abstract class WeatherPresenter extends BasePesenter {
    public abstract void getWeatherData(String format, String city);
}

public class WeatherPresenterImp extends WeatherPresenter implements WeatherOnListener{
    /**
     * WeatherModel和WeatherView都是通過接口來實現,這就Java設計原則中依賴倒置原則使用
     */
    private WeatherModel mWeatherModel;
    private WeatherView mWeatherView;

    public WeatherPresenterImp( WeatherView mWeatherView) {
        this.mWeatherModel = new WeatherModelImp(this);
        this.mWeatherView = mWeatherView;
    }
    @Override
    public void getWeatherData(String format, String city) {
        mWeatherView.showProgress();
        addSubscription(mWeatherModel.getWeatherData(format,city));
    }

    @Override
    public void onSuccess(WeatherData s) {
        mWeatherView.loadWeather(s);
        mWeatherView.hideProgress();
        Log.d("-------", "onSuccess() called with: " + "s = [" + s.toString() + "]");
    }

    @Override
    public void onFailure(Throwable e) {
        mWeatherView.hideProgress();
        Log.d("-------", "onFailure" + e.getMessage());
    }
}

7)view層

public interface WeatherView {
    void showProgress();
    void hideProgress();
    void loadWeather(WeatherData weatherData);
}

8)監聽器

public interface WeatherOnListener {
    void onSuccess(WeatherData s);
    void onFailure(Throwable e);
}

9)LodingHelper

public class LoadingUIHelper {

    private static Dialog dialog;

    public static void showDialogForLoading(final Context context, String tipContext){
        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
        dialog = builder.create();
        builder.setTitle("");
        builder.setMessage(tipContext);
        builder.setIcon(R.mipmap.ic_launcher);
        builder.setNegativeButton("取消",new DialogInterface.OnClickListener(){
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialog.dismiss();
            }
        });
        builder.setPositiveButton("確定",new DialogInterface.OnClickListener(){

            @Override
            public void onClick(DialogInterface dialogInterface, int i) {

            }
        });
        builder.show();

    }

    public static void hideDialogForLoading(){
        if(dialog != null){
            dialog.dismiss();
        }
    }
}

10)在Activity中處理

public class MainActivity extends AppCompatActivity implements WeatherView{

    private WeatherPresenterImp mWeatherPresenter;
    private TextView textView1;
    private TextView textView2;
    private TextView textView3;
    private TextView textView4;
    private TextView textView5;
    private TextView textView6;
    private TextView textView7;
    private TextView textView8;
    private TextView textView9;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWeatherPresenter = new WeatherPresenterImp(this);
        mWeatherPresenter.getWeatherData("2", "蘇州");
        textView1 = (TextView) findViewById(R.id.textView1);
        textView2 = (TextView) findViewById(R.id.textView2);
        textView3 = (TextView) findViewById(R.id.textView3);
        textView4 = (TextView) findViewById(R.id.textView4);
        textView5 = (TextView) findViewById(R.id.textView5);
        textView6 = (TextView) findViewById(R.id.textView6);
        textView7 = (TextView) findViewById(R.id.textView7);
        textView8 = (TextView) findViewById(R.id.textView8);
        textView9 = (TextView) findViewById(R.id.textView9);
    }

    @Override
    public void showProgress() {
        LoadingUIHelper.showDialogForLoading(this,"獲取數據");
    }

    @Override
    public void hideProgress() {
        LoadingUIHelper.hideDialogForLoading();
        Toast.makeText(this,"服務器異常",Toast.LENGTH_SHORT).show();
        mWeatherPresenter.onUnsubscribe();
    }

    @Override
    public void loadWeather(WeatherData weatherData) {
        Log.d("weatherData", "weatherData==" + weatherData.toString());
        textView1.setText("城市:"+weatherData.getResult().getToday().getCity());
        textView2.setText("日期:"+weatherData.getResult().getToday().getWeek());
        textView3.setText("今日溫度:"+weatherData.getResult().getToday().getTemperature());
      //  textView4.setText("天氣標識:" +WeatherIDUtils.transfer(weatherData.getResult().getToday().getWeather_id().getFa()));
        textView5.setText("穿衣指數:" + weatherData.getResult().getToday().getDressing_advice());
        textView6.setText("乾燥指數:"+weatherData.getResult().getToday().getDressing_index());
        textView7.setText("紫外線強度:"+weatherData.getResult().getToday().getUv_index());
        textView8.setText("穿衣建議:"+weatherData.getResult().getToday().getDressing_advice());
        textView9.setText("旅遊指數:"+weatherData.getResult().getToday().getTravel_index());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消註冊
        mWeatherPresenter.onUnsubscribe();
    }
發佈了30 篇原創文章 · 獲贊 18 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章