Successfully reported this slideshow.
Your SlideShare is downloading. ×

When Android meets RxJava

Ad

当Android遇上RxJava
By 宇行信(yuxingxin)
2016.1.10

Ad

RxJava+Android
• 1.介绍ReactiveX、RxJava
• 2.常见Android开发中遇到的使用场景
• 3.关于RxJava与Android的学习

Ad

ReactiveX
• 1.扩展的观察者模式
• 通过订阅可观测对象的序列流然后做出反应。
• 2.迭代器模式
• 对对象序列进行迭代输出从而使订阅者可以依次对其处理
。
• 3.函数式编程思想
• 简化问题的解决的步骤,让你的代码更优雅和简洁

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Loading in …3
×

Check these out next

1 of 39 Ad
1 of 39 Ad

More Related Content

When Android meets RxJava

  1. 1. 当Android遇上RxJava By 宇行信(yuxingxin) 2016.1.10
  2. 2. RxJava+Android • 1.介绍ReactiveX、RxJava • 2.常见Android开发中遇到的使用场景 • 3.关于RxJava与Android的学习
  3. 3. ReactiveX • 1.扩展的观察者模式 • 通过订阅可观测对象的序列流然后做出反应。 • 2.迭代器模式 • 对对象序列进行迭代输出从而使订阅者可以依次对其处理 。 • 3.函数式编程思想 • 简化问题的解决的步骤,让你的代码更优雅和简洁
  4. 4. ReactiveX已经实现的语言版本和平台版 本
  5. 5. 为什么说是扩展的观察者模式 • GoF中的观察者模式:被观察者发出事件,然后观 察者(事件源)订阅然后进行处理。 • 扩展:如果没有观察者,被观察者是不会发出任何事 件的。另外知道事件何时结束,还有错误通知处理
  6. 6. 迭代器模式 提供一种方法顺序访问一个聚合对象中的各种元素, 而又不暴露该对象的内部表示 《RxJava Essentials》一书做的的对比:迭代器模式在事件处理上采用的是“同步/拉式” 的方式,而被观察者采用的是“异步/推式”的方式,而对观察者而言,显然后者更灵活。
  7. 7. 函数式编程 来自《给Android开发者的RxJava详解》的代码:对比一下是不是下 面更简洁与优雅?
  8. 8. RxJava • 1.RxJava的核心 • 2.RxJava操作符 • 3.RxJava扩展
  9. 9. RxJava核心 • Observable(被观察者,也就是事件源)和Subscriber(观察者)
  10. 10. 写成匿名函数: 用Java 8 lambdas(Retrolambda)表达式
  11. 11. • Observable • OnSubscribe • Observer • Subscription • Subscriber 容易混淆的类/接口
  12. 12. 宝石图 http://rxmarbles.com/
  13. 13. RxJava操作符 • 创建操作符:Create, Defer, From, Interval, Just, Range, Repeat, Timer等。 String[] strings = {"张三","李四","王五","赵六"}; Observable.from(strings) .subscribe(new Action1<String>() { @Override public void call(String s) { Log.i("name",s); } });
  14. 14. RxJava操作符 • 变换操作:Map、FlatMap、ConcatMap等 public void showUserName(String userName){ textView.setText(userName); } public void showUserName(String userName){ Observable.just(userName).subscribe( new Action1<String>(){ @Override public void call(String s){ textView.setText(s); } }); }
  15. 15. 如果需要在显示前对这个字符串做处理,然后再展示,比如加“张 三,你好” 方法1:我们可以对字符串本身操作 方法2:我们可以放到Action1.call()方法里做处理 方法3:使用操作符做变换:map public void showUserName(String userName){ Observable.just(userName).map(new Func1<String,String>(){ public String call(String text){ return handleUserName(text); } }).subscribe( new Action1<String>(){ public void call(String s){ textView.setText(s); } }); }
  16. 16. flatMap() • 打印出中国的所有省份名称。 List<Province> provinceList = … Observable.from(provinceList) .map(new Func1<Province,String>(){ @Override public String call(Province province){ return province.getName(); } }).subscribe(new Action1<String>(){ @Override public void call(String s){ Log.i(“省份名称”,s) } });
  17. 17. flatMap() 打印出中国每个省份的所有城市 List<Province> provinceList = … Observable.from(provinceList) .subscribe(new Action1<Province>(){ @Override public void call(Province province){ List<City> cities = province.getCities(); for (int i = 0; i < cities.size(); i++) { City city = cities.get(i); Log.i(“城市”, city.getName()); } } });
  18. 18. List<Province> provinceList = … Observable.from(provinceList) .flatMap(new Func1<Province,Observable<City>>(){ @Override public Observable<City> call(Province province){ return Observable.from(province.getCities()); } }) .subscribe(new Action1<City>(){ @Override public void call(City city){ Log.i(“城市”, city.getName()); } }); flatMap()
  19. 19. flatMap()扩展 回调地狱 restAdapter.getApiService().getToken(new Callback<String>(){ @Override public void success(String token) { restAdapter.getApiService().getUserInfo(token,new Callback<UserInfo> @Override public void success(UserInfo userInfo) { showMessage(userInfo.getUser); } @Override public void failure(RetrofitError error) { //处理错误 ... } }); } @Override public void failure(RetrofitError error) { // Error handling ... } });
  20. 20. 解决回调地狱 restAdapter.getApiService() .getToken() .flatMap(new Func1<String,Observable<UserInfo>>(){ @Override public Observable<UserInfo> call(String token){ return restAdapter.getApiService().getUserInfo(token); } }) .subscribe(new Action1<UserInfo>(){ @Override public void call(UserInfo userInfo){ showMessage(userInfo.getUser); } })
  21. 21. 异步 调度器Scheduler: Schedulers.immediate() Schedulers.newThread() Schedulers.io() Schedulers.computation() AndroidSchedulers.mainThread() 操作符: subscribeOn():指定 subscribe() 所发生的线程 observeOn():指定 Subscriber 所运行在的线程 Schedulers.trampoline()
  22. 22. 修改之前的例子 restAdapter.getApiService().getToken() .flatMap(new Func1<String,Observable<UserInfo>>(){ @Override public Observable<UserInfo> call(String token){ return restAdapter.getApiService().getUserInfo(token); } }) .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程 .observeOn(AndroidSchedulers.mainThread())// 指定 Subscriber 的 回调发生在主线程 .subscribe(new Action1<UserInfo>(){ @Override public void call(UserInfo userInfo){ showMessage(userInfo.getUser); } })
  23. 23. 操作符复用 <T> Observable<T> applySchedulers(Observable<T> observable) { return observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } applySchedulers(restAdapter.getApiService().getToken() .flatMap(new Func1<String,Observable<UserInfo>>(){ @Override public Observable<UserInfo> call(String token){ return restAdapter.getApiService().getUserInfo(token); } }) ).subscribe(new Action1<UserInfo>(){ @Override public void call(UserInfo userInfo){ showMessage(userInfo.getUser); } })
  24. 24. 转换器与Compose() Transformer:Func1<Observable<T>, Observable<R>> <T> Transformer<T, T> applySchedulers() { return new Transformer<T, T>() { @Override public Observable<T> call(Observable<T> observable) { return observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } }; }
  25. 25. restAdapter.getApiService().getToken() .flatMap(new Func1<String,Observable<UserInfo>>(){ @Override public Observable<UserInfo> call(String token){ return restAdapter.getApiService().getUserInfo(token); } }) .compose(applySchedulers()) .subscribe(new Action1<UserInfo>(){ @Override public void call(UserInfo userInfo){ showMessage(userInfo.getUser); } }) Compose()操作符
  26. 26. 其他操作符 e, Distinct, ElementAt, Filter, First, Last, Sample, Skip, SkipLa Debounce:“去抖”,只有在空闲了一段时间后才发射数 据,过滤掉发射速率过快的数据项 Sample:“采样”,定期发射Observable最近发射的数据项 自定义操作符
  27. 27. 总结 • 将一个为数字的字符串数组元素转换为数字 • 过滤掉大于10的数字 • 去重 • 取最后面3个元素 • 累计求和
  28. 28. Observable .from(numbers) .map(s -> Integer.parseInt(s)) .filter(s -> s < 10) .distinct() .takeLast(3) .reduce((number1, number2) -> number1 + number2) ) .subscribe(i -> System.out.println(i));//16 String[] numbers = {"11", "2", "2", "13", "4", "5", "7"}
  29. 29. 扩展 1.Rxbinding:用RxJava实现onClick,TextWatcher,check等事件绑定 2.RxBus:用RxJava实现EventBus或者Otto 3.RxPreferences:用RxJava实现Android中的SharedPreferences 4.RxLifecycle:用来严格控制由于发布了一个订阅后,由于没有及时 5.ReactiveNetwork:使用RxJava来监听网络连接状态和wifi信号 强度变化 6.RxPermissions:针对 Android 6.0 权限管理进行一个 Rx 封装 的一个类库 7.rxloader:用RxJava对loader的一个封装 还有更多…
  30. 30. Android应用场景 1.避免嵌套回调地狱问题 2.使用debounce减少频繁的网络请求。避免每输入(删除)一个字就做一次联想 3.使用combineLatest合并最近N个结点,注册的时候所有输入信息(邮箱、密码、电 4.使用merge合并两个数据源,最后做统一处理 5.使用concat和first做缓存,依次检查memory、disk和network中是否存在数据,任 6.使用timer做定时操作 7.使用interval做周期性操作 8.使用throttleFirst防止按钮重复点击 9.做响应式的界面 更多…
  31. 31. RxTextView.textChanges(searchEditText) .debounce(150, MILLISECONDS) .switchMap(Api::searchItems) .subscribe(this::updateList, t->showError());
  32. 32. Observable.merge(getNews(), getHotNews(), new Func2<Response<News>, MyResponse @Override public Boolean call(Response<News> response, Response<News> response2) { mData.clear(); mData.addAll(response); mData.addAll(response2.msg); return true; } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<Boolean>() { @Override public void onCompleted() {} @Override public void onError(Throwable e) {} @Override public void onNext(Boolean o) { mAdapter.notifyDataSetChanged(); } });
  33. 33. RxView.clicks(button) .throttleFirst(1, TimeUnit.SECONDS) .subscribe(new Observer<Object>() { @Override public void onCompleted() { log.d ("completed"); } @Override public void onError(Throwable e) { log.e("error"); } @Override public void onNext(Object o) { log.d("button clicked"); } });
  34. 34. SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferen RxSharedPreferences rxPreferences = RxSharedPreferences.create(preferences Preference<Boolean> checked = rxPreferences.getBoolean("checked", true); CheckBox checkBox = (CheckBox) findViewById(R.id.cb_test); RxCompoundButton.checkedChanges(checkBox) .subscribe(checked.asAction());
  35. 35. Observable<String> memory = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { if (memoryCache != null) { subscriber.onNext(memoryCache); } else { subscriber.onCompleted(); } } }); Observable<String> disk = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { String cachePref = rxPreferences.getString("cache").get(); if (!TextUtils.isEmpty(cachePref)) { subscriber.onNext(cachePref); } else { subscriber.onCompleted(); } } });
  36. 36. Observable<String> network = Observable.just("network"); //依次检查memory、disk、network Observable.concat(memory, disk, network) .first() .subscribeOn(Schedulers.newThread()) .subscribe(s -> { memoryCache = "memory"; System.out.println("--------------subscribe: " + s); });
  37. 37. 参考 • http://gank.io/post/560e15be2dca930e00da1083 • http://blog.csdn.net/lzyzsd/article/details/41833541 • http://blog.csdn.net/theone10211024/article/details /50435325 • 《RxJava Essentials》 • http://reactivex.io
  38. 38. 关于 微博:宇行信 移动开发在线分享站:http://mobdevgroup.com 知乎:yuxingxin
  39. 39. Thanks

×