您的位置:首页 > 移动开发 > Android开发

Android笔记__RxJava太难理解?用callBack的方式实现RxJava mini

2017-03-31 15:33 387 查看
每次看到RxJava的文章都情不自禁的说道观察者模式,总是被绕得一头雾水不知所云。

后来看到一个神人写的博客,才明白,所谓的观察者模式最直观的代码表现就是控件的OnClickListener。

下面是他的原话:

程序的观察者模式和这种真正的『观察』略有不同,观察者不需要时刻盯着被观察者(例如 A 不需要每过 2ms 就检查一次 B 的状态),而是采用注册(Register)或者称为订阅(Subscribe)的方式,告诉被观察者:我需要你的某某状态,你要在它变化的时候通知我。 Android 开发中一个比较典型的例子是点击监听器 
OnClickListener
 。对设置
OnClickListener
 来说, 
View
 是被观察者, 
OnClickListener
 是观察者,二者通过 
setOnClickListener()
 方法达成订阅关系。订阅之后用户点击按钮的瞬间,Android
Framework 就会将点击事件发送给已经注册的 
OnClickListener
 。采取这样被动的观察方式,既省去了反复检索状态的资源消耗,也能够得到最高的反馈速度。当然,这也得益于我们可以随意定制自己程序中的观察者和被观察者,而警察叔叔明显无法要求小偷『你在作案的时候务必通知我』。

观察者模式用一句话说明的话,大概可以这么说:“这是我电话号码,有事打给我!”

本文是用callBack的形式实现一个RxJava的mini版本,只有简单的两个类,主要是通过固定好的一些抽象规则,将不同的逻辑处理的过程规范化,同时简化异步处理的过程,减少线程之间通讯的不必要的繁琐代码。相比与RxJava,最大的特点是小,小的不能再小,逻辑结构和处理过程更加的清晰明了,没那么复杂理论、定义,上手就用。

下面是callBack的形式实现的一个RxJava的mini版本,模拟验证手机号码和验证码信息过程的调用:

public void test(){
XyObservable.addTask(new XyCallBack() {
public void beforeStart(){
ALog.e("beforeStart");
phone=etPhone.getText().toString();
code=etCode.getText().toString();
}
@Override
public void run() {
ALog.e("run");
etPhone.setText("哈哈哈");
if(TextUtils.isEmpty(phone)){
setError("手机号为空");
return;
}

if(phone.length()!=11){
setError("手机格式不对");
return;
}

if(!code.equals("8888")){
setError("验证码错误");
}
}

@Override
public void finish() {
ALog.e("finish");
ToastUtils.showToast(getActivity(),"验证通过");
}

public void error(String str){
ALog.e("error");
if(!TextUtils.isEmpty(str)){
ToastUtils.showToast(getActivity(),str);
}else{
ToastUtils.showToast(getActivity(),"未知错误");
}
}
});
}

每一个类的意思可以直接看callBack的源码:

package com.imxiaoyu.common.observable;

/**
* Created by XiaoYu on 2017/3/31.
*/

public abstract class XyCallBack {
public boolean error=false;//是否有错误需要返回
public String errorStr;//错误信息

/**
* 在开始前做一些事情,UI线程
*/
public void beforeStart(){}

/**
* 需要执行的任务,线程池调用
*/
public abstract void run();

/**
* 执行完成,如果isUiThread返回的是true,那么finish就是在UI线程中返回,否则就是在子线程中返回
*/
public abstract void finish();

/**
* 过程,执行了start之后会执行process,线程池调用
*/
public void process(){}

/**
* 设置错误,设置了错误之后不会回调finish(),而是会回调error()
* @param str 错误信息
*/
public void setError(String str){
this.error=true;
this.errorStr=str;
}

/**
* 错误
*/
public void error(String str){}

/**
* 是否在UI线程执行返回
* @return
*/
public boolean isUrThread(){
return true;
}
}

另外一个类XyObservable.java的代码:

package com.imxiaoyu.common.observable;

import android.os.Handler;
import android.os.Message;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* Created by XiaoYu on 2017/3/31.
*/

public class XyObservable {
private static ExecutorService executorService = Executors.newFixedThreadPool(6);

/**
* 设置线程池的线程个数,默认6
* @param num
*/
public static void setThreadNum(int num) {
executorService = Executors.newFixedThreadPool(num);
}

public static void addTask(final XyCallBack callBack) {
callBack.beforeStart();//UI线程中做准备工作
executorService.execute(new Runnable() {
@Override
public void run() {
Message msg = new Message();
msg.obj = callBack;
try {
callBack.run();//执行任务
callBack.process();//执行过程任务
if (callBack.isUrThread()) {
//在主线程中回调
msg.what = 0;
handler.sendMessage(msg);
} else {
//子线程中直接回调
callBack.finish();
}
} catch (Exception e) {
//发生错误
msg.what = 1;
handler.sendMessage(msg);
}
}
});
}

/**
* 主线程回调
*/
public static Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
try {
if (msg != null && msg.obj != null) {
XyCallBack callBack = (XyCallBack) msg.obj;
if (msg.what == 0) {
if (callBack.error) {
callBack.error(callBack.errorStr);
} else {
callBack.finish();

929e
}
}
if (msg.what == 1) {
callBack.error(callBack.errorStr);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
http://doutugongchang.com
参考博客

http://gank.io/post/560e15be2dca930e00da1083 http://www.jianshu.com/p/5e93c9101dc5[/code]  
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐