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实际项目中的应用)的效果:
主页内容:
右侧栏天气列表:
左侧栏城市列表
首先看看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(); }
//获取天气数据 @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