RxAndroid 应用(一)(简易天气App)

       RxAndroid 应用(一)(简易天气App)

       RxAndroid 应用(二)(简易天气App)

       RxAndroid 应用(三)(简易天气App之Observable内存泄露)

       RxAndroid 应用(四)(简易天气App之RxBus)

     

      关于RxJava、RxAndroid 详解请看 RxJava、RxAndroid详解

      关于MVP的详解请移步 Android应用架构之Android MVP使用

      关于Retrofit的使用介绍请移步Android应用架构之Retrofit、RxAndroid使用 


今天开始我主要应用RxAndroid、MVP、Retrofit实现一个简单的app,以此来介绍RxAndroid的使用。

首先看看需要实现简易天气App(只是为了介绍如何使用RxJava在Android实际项目中的应用)的效果:

主页内容:

RxAndroid 应用(一)(简易天气App)_第1张图片


右侧栏天气列表:



左侧栏城市列表

RxAndroid 应用(一)(简易天气App)_第2张图片


首先看看Activity主要代码(使用MVP模式):

        //调用Presenter的方法获取数据
        mMainPresenter = new MainPresenterImpl(this);
        mMainPresenter.getPlaceData();
        mMainPresenter.getWeatherData("成都");

    //显示主页和右侧栏天气数据
    public void setupWeatherData(WeatherResponse weatherResponse) {
        if (weatherResponse == null) return;
        setTitleText(DateUtils.getWeekDay(weatherResponse.date));
        if (weatherResponse.results != null && weatherResponse.results.size() > 0) {
            WeatherResult result = weatherResponse.results.get(0);
            mTvCity.setText(getString(R.string.city, result.currentCity));
            mTvPm25.setText(getString(R.string.pm25, result.pm25));

            mWeatherDataAdapter.setData(result.weather_data);
            mWeatherDataAdapter.notifyDataSetChanged();

            mWeatherExtraAdapter.setData(result.index);
            mWeatherExtraAdapter.notifyDataSetChanged();
        }
    }

    //显示左侧栏城市列表
    @Override
    public void setupPlaceData(List<Place> placeList) {
        if (placeList == null) {
            return;
        }
        mPlaceAdapter.setData(placeList);
        mPlaceAdapter.notifyDataSetChanged();
    }

接下来看看如何在Presenter中应用RxJava、RxAndroid获取数据

    //获取天气数据
    @Override
    public void getWeatherData(String place) {
        if (TextUtils.isEmpty(place)) {
            return;
        }
        mMainView.showProgress();
        ServiceManager.getInstance().getApiService().getWeatherInfo(place, Constants.BAIDU_AK)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<WeatherResponse>() {
                    @Override
                    public void onCompleted() {
                        Log.e(TAG, "onCompleted");
                        mMainView.hideProgress();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, e.getMessage(), e);
                        mMainView.hideProgress();
                    }

                    @Override
                    public void onNext(WeatherResponse weatherResponse) {
                        mMainView.setupWeatherData(weatherResponse);
                    }
                });
    }



public interface ApiService {

    /*@GET("service/getIpInfo.php")
    Call<GetIpInfoResponse> getIpInfo(@Query("ip") String ip);*/

    @GET("service/getIpInfo.php")
    Observable<GetIpInfoResponse> getIpInfo(@Query("ip") String ip);


    //http://api.map.baidu.com/telematics/v3/weather?location=%E6%88%90%E9%83%BD&output=json&ak=MPDgj92wUYvRmyaUdQs1XwCf
    @GET("/telematics/v3/weather?output=json")
    Observable<WeatherResponse> getWeatherInfo(@Query("location") String location, @Query("ak") String ak);
}

如上所述,我们通过百度api获取天气数据使用的是Retrofit框架,它能自动的返回Observable对象。

那么我们如何通过RxJava获取本地文件中的城市列表呢?(为了方便演示,我将城市列表作为一个json字符串放于文件中)

    @Override
    public void getPlaceData() {
        PlaceRepository repository = new PlaceRepository();
        repository.getPlaceList(BaseApplication.getInstance())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<List<Place>>() {
                    @Override
                    public void onNext(List<Place> places) {
                        mMainView.setupPlaceData(places);
                    }

                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }
                });
    }

public class PlaceRepository {

    public Observable<List<Place>> getPlaceList(final Context context) {
        return Observable.create(new Observable.OnSubscribe<List<Place>>() {
            @Override
            public void call(Subscriber<? super List<Place>> subscriber) {
                try {
                    AssetManager assertManager = context.getAssets();
                    InputStream inputStream = assertManager.open("place");
                    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                    byte[] data = new byte[1024];
                    int count = -1;
                    while((count = inputStream.read(data,0, 1024)) != -1) {
                        outStream.write(data, 0, count);
                    }
                    String json =  new String(outStream.toByteArray(),"UTF-8");
                    Gson gson = new GsonBuilder().create();
                    List<Place> placeList = gson.fromJson(json, new TypeToken<List<Place>>() {}.getType());
                    subscriber.onNext(placeList);
                } catch (Exception e) {
                    subscriber.onError(e);
                }
                subscriber.onCompleted();
            }
        });
    }
}
通过上述代码,我们就能完成界面所示功能了,是不是省去了Handler callback,new Thread()这些操作了,这就为什么说RxJava是用来解决Callback Hell的。

这里的代码会看起来不是那么好的地方:在Activity中分别调用了获取天气数据和城市列表的方法,那么问题来了,如果取数据的时候显示了process Dialog, 我该在什么时候结束呢,写flag判断?请看下章博文分解。

代码地址:https://github.com/mickyliu945/CommonProj


你可能感兴趣的:(RxAndroid 应用(一)(简易天气App))