//—————————————4: Action0和Action1 讲解————————————————————–
/**
* 肯定有同学对Action0和Action1很困惑,就像当初我刚看到那样子;
* 那就听听扔物线给大家讲一下:
*
* MaLin:扔物线大哥,你能够给我们讲解一下Action0和Action1是什么,以及他们之间的区别吗?
*
* 扔物线:大家好,我简单的解释一下:
* Action0 是 RxJava 的一个接口,它只有一个方法 call(),这个方法是无参无返回值的;
* 由于 onCompleted() 方法也是无参无返回值的,因此 Action0 可以被当成一个包装对象,
* 将 onCompleted() 的内容打包起来将自己作为一个参数传入 subscribe() 以实现不完整定义的回调。
* 这样其实也可以看做将 onCompleted() 方法作为参数传进了 subscribe(),相当于其他某些语言中的『闭包』。
*
* Action1 也是一个接口,它同样只有一个方法 call(T param),这个方法也无返回值,但有一个参数;
* 与 Action0 同理,由于 onNext(T obj) 和 onError(Throwable error) 也是单参数无返回值的,
* 因此 Action1 可以将 onNext(obj) 和 onError(error) 打包起来传入 subscribe() 以实现不完整定义的回调。
* 事实上,虽然 Action0 和 Action1 在 API 中使用最广泛,但 RxJava 是提供了多个 ActionX 形式的接口 (例如 Action2, Action3) 的,
* 它们可以被用以包装不同的无返回值的方法。
*/
//---------------------------------------5: 休息一下!推荐两个好用的日志查看工具-------------------------------------------------------------
//1.[logger](https://github.com/orhanobut/logger) | 一个简洁,优雅,功能强大的Android日志输出工具
//2.[pidcat](https://github.com/JakeWharton/pidcat)|JakeWharton项目一个简洁,优雅的,彩色日志终端查看库|在终端过滤日志信息
/**
* 使用com.github.orhanobut:logger 库可以查看当前的线程
* ╔════════════════════════════════════════════════════════════════════════════════════════
D ║ Thread: main
D ╟────────────────────────────────────────────────────────────────────────────────────────
D ║ MainActivity$11.onNext (MainActivity.java:338)
D ║ MainActivity$11.onNext (MainActivity.java:354)
D ╟────────────────────────────────────────────────────────────────────────────────────────
D ║ 观察者 onNext()
D ╚════════════════════════════════════════════════════════════════════════════════════════
D ╔════════════════════════════════════════════════════════════════════════════════════════
D ║ Thread: main
D ╟────────────────────────────────────────────────────────────────────────────────────────
D ║ SafeSubscriber.onCompleted (SafeSubscriber.java:83)
D ║ MainActivity$11.onCompleted (MainActivity.java:341)
D ╟────────────────────────────────────────────────────────────────────────────────────────
D ║ 观察者 onCompleted()
D ╚════════════════════════════════════════════════════════════════════════════════════════
*/
//---------------------------------------6 线程控制-Scheduler-------------------------------------------------------------
/**
* 显示图片
* 后台线程取数据,主线程显示
* 加载图片将会发生在 IO 线程,而设置图片则被设定在了主线程。这就意味着,即使加载图片耗费了几十甚至几百毫秒的时间,也不会造成丝毫界面的卡顿。
*/
private void method6() {
final int drawableRes = R.mipmap.malin;
Observable.create(new Observable.OnSubscribe<Drawable>() { //1:被观察者
@Override
public void call(Subscriber<? super Drawable> subscriber) {
Logger.d("被观察者");
Drawable drawable = getResources().getDrawable(drawableRes);
subscriber.onNext(drawable);
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io())//事件产生的线程。指定 subscribe() 发生在 IO 线程
// doOnSubscribe() 之后有 subscribeOn() 的话,它将执行在离它最近的 subscribeOn() 所指定的线程。这里将执行在主线程中
.doOnSubscribe(new Action0() {
@Override
public void call() {
if (mProgressBar != null) {
mProgressBar.setVisibility(View.VISIBLE);//显示一个等待的ProgressBar--需要在主线程中执行
}
}
})
.observeOn(AndroidSchedulers.mainThread())//指定 Subscriber 所运行在的线程。或者叫做事件消费的线程
.subscribe(new Subscriber<Drawable>() { //3:订阅 //2:观察者
@Override
public void onCompleted() {
if (mProgressBar!=null){
mProgressBar.setVisibility(View.GONE);
}
Logger.d("观察者 onCompleted()");
Toast.makeText(MainActivity.this, "观察者 onCompleted()", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
if (mProgressBar!=null){
mProgressBar.setVisibility(View.GONE);
}
Logger.d("观察者 onError()");
Toast.makeText(MainActivity.this, "观察者 onError() " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(Drawable drawable) {
Toast.makeText(MainActivity.this, "观察者 onNext()", Toast.LENGTH_SHORT).show();
Logger.d("观察者 onNext()");
mImageView.setImageDrawable(drawable);
}
});
}
//—————————————7: 变换 map()————————————————————-
private void method7() {
final int drawableRes = R.mipmap.malin;
//1:被观察者
Observable.just(drawableRes)//输入类型 int
.map(new Func1<Integer, Drawable>() {
@Override
public Drawable call(Integer integer) {// 参数类型 String
Logger.d("integer:" + integer);
return getResources().getDrawable(integer);
}
})
.subscribeOn(Schedulers.io())//事件产生的线程。指定 subscribe() 发生在 IO 线程
//doOnSubscribe() 之后有 subscribeOn() 的话,它将执行在离它最近的 subscribeOn() 所指定的线程。这里将执行在主线程中
.doOnSubscribe(new Action0() {
@Override
public void call() {
if (mProgressBar != null) {
mProgressBar.setVisibility(View.VISIBLE);//显示一个等待的ProgressBar--需要在主线程中执行
}
}
})
.observeOn(AndroidSchedulers.mainThread())//指定 Subscriber 所运行在的线程。或者叫做事件消费的线程
.subscribe(new Subscriber<Drawable>() { //3:订阅 //2:观察者
@Override
public void onCompleted() {
if (mProgressBar != null) {
mProgressBar.setVisibility(View.GONE);
}
Logger.d("观察者:onCompleted()");
}
@Override
public void onError(Throwable e) {
if (mProgressBar != null) {
mProgressBar.setVisibility(View.GONE);
}
Toast.makeText(MainActivity.this, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
Logger.d("观察者:onError(Throwable e):" + e.getMessage());
}
@Override
public void onNext(Drawable drawable) {
mImageView.setImageDrawable(drawable);
Logger.d("观察者:onNext(Drawable drawable):" + drawable.toString());
}
});
}
//---------------------------------------8: 练习 中途休息一下-------------------------------------------------------------
//演示嵌套循环
private void method8() {
ArrayList<Student> students = DataFactory.getData();
int size = students.size();
for (int i = 0; i < size; i++) {
Logger.d("姓名:" + students.get(i).name);
int sizeCourses = students.get(i).courses.size();
for (int j = 0; j < sizeCourses; j++) {
Logger.d("课程:" + students.get(i).courses.get(j).name);
}
}
}
/**
* 需要:依次输入学生的姓名:将每个学生(实体对象)依次发射出去
* RxJava解决方案:
* {@link #method8()}
*/
private void method9() {
//just(T...): 将传入的参数依次发送出来,实现遍历的目的
Observable.from(DataFactory.getData())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Student>() {
@Override
public void call(Student student) {
Logger.d("观察者:" + student.name);
}
});
}
/**
* 需要:输出学生的姓名:将每个学生的(姓名)依次发射出去
* RxJava解决方案
* {@link #method9()}
*/
private void method10() {
//1:被观察者
//2:数据转换
//3:事件产生的线程。
//4:事件消费的线程。
//5:被观察者被观察者订阅
//6:观察者
Observable.from(DataFactory.getData())
.map(new Func1<Student, String>() {
@Override
public String call(Student student) {
return student.name;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
Logger.d("观察者:onCompleted()");
}
@Override
public void onError(Throwable e) {
Logger.d("观察者:onError(Throwable e) " + e.getMessage());
}
@Override
public void onNext(String s) {
Logger.d("观察者:onNext(String s) " + s);
}
});
}
/**
* 需要:输出学生的姓名:将每个学生的(姓名)依次发射出去,对method9()的简化
* RxJava解决方案
* 输出学生的姓名
* {@link #method10()}
*/
private void method11() {
Observable.from(DataFactory.getData())
.map(new Func1<Student, String>() {
@Override
public String call(Student student) {
return student.name;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Logger.d("观察者:" + s);
}
});
}
//---------------------------------------9: 引入flatmap()-------------------------------------------------------------
/**
* 需要:输出每一个学生所有选修的课程
* 嵌套循环的RxJava解决方案
* 输出每一个学生选修的课程
* {@link #method11()}
*/
private void method12() {
//1:被观察者
//2:被观察者被观察者订阅
//3:观察者
Observable.from(DataFactory.getData())
.subscribe(new Subscriber<Student>() {
@Override
public void onCompleted() {
Logger.d("观察者:onCompleted()");
}
@Override
public void onError(Throwable e) {
Logger.d("观察者:onError(Throwable e)" + e.getMessage());
}
@Override
public void onNext(Student student) {
ArrayList<Course> courses = student.courses;
for (Course course : courses) {
Logger.d("观察者:" + course.name);
}
}
});
}
/**
* 需要:输出每一个学生选修的课程,对method12的简化
* 嵌套循环的RxJava解决方案
* {@link #method12()}
* Student->ArrayList<Course>
*/
private void method13() {
Observable.from(DataFactory.getData())
.map(new Func1<Student, ArrayList<Course>>() {
@Override
public ArrayList<Course> call(Student student) {
return student.courses;
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<ArrayList<Course>>() {
@Override
public void call(ArrayList<Course> courses) {
for (int i = 0; i < courses.size(); i++) {
Logger.d("观察者:" + courses.get(i).name);
}
}
});
}
//---------------------------------------10: flatMap()的使用-------------------------------------------------------------
/**
* 需要:输出每一个学生选修的课程,对method13的简化
* 嵌套循环的RxJava解决方案
* {@link #method13()}
* Student -> ArrayList<Course> -> Observable<Course> ->
*/
private void method14() {
//1:被观察者
//2:数据转换
//3:事件产生的线程。
//4:事件消费的线程。
//5:被观察者被观察者订阅
//6:观察者
// Student->Course
Observable.from(DataFactory.getData())
.flatMap(new Func1<Student, Observable<Course>>() {
@Override
public Observable<Course> call(Student student) {
return Observable.from(student.courses);
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Course>() {
@Override
public void call(Course course) {
Logger.d("观察者:" + course.name);
}
});
}
//---------------------------------------10: RxBinding的引入-------------------------------------------------------------
/**
* 需要防止快速连续点击,短时间内连续点击.
*/
private void method15() {
mImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (ClickUtils.isFastDoubleClick()) {
ToastUtil.getInstance().showToast(MainActivity.this, "点击过快啦");
return;
}
ToastUtil.getInstance().showToast(MainActivity.this, "匿名内部类实现click");
}
});
}
});
}