主要改变的就是HandlerFactory和RXBus这两个类,又加了几个方法,这一次使用到了反射。java
其余的类没有改变,在上一篇文章中均可以找到源码。android
新的RxBus以下所示(仍是基于网上其余人的改的):数组
package com.mitnick.root.mycample.util.rxbus; import android.util.Log; import com.mitnick.root.mycample.util.rxbus.responslink.ResponseNode; import rx.Observable; import rx.Subscription; import rx.functions.Action1; import rx.functions.Func1; import rx.subjects.PublishSubject; import rx.subjects.SerializedSubject; import rx.subjects.Subject; /** * Created by root on 16-4-12. * 事件体只会被发射到相对应的主题的订阅者 */ public class RxBus { private static volatile RxBus defaultInstance; // 主题 private final Subject bus; public RxBus() { bus = new SerializedSubject<>(PublishSubject.create()); } // 单例RxBus public static RxBus getDefault() { RxBus rxBus = defaultInstance; if (defaultInstance == null) { synchronized (RxBus.class) { rxBus = defaultInstance; if (defaultInstance == null) { rxBus = new RxBus(); defaultInstance = rxBus; } } } return rxBus; } /** * 事件总线发射一个事件 * @Param rxBusEvent : 事件体 * */ public void post (RxBusEvent rxBusEvent) { bus.onNext(rxBusEvent); } /** * 订阅事件总线的某一个主题 * @Param tag : 订阅的主题,事件总线只会对感兴趣的主题发射事件 * @Param eventType : 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者 * */ public <T> Observable<T> toObserverable (Class<T> eventType) { return bus.ofType(eventType); // 这里感谢小鄧子的提醒: ofType = filter + cast // return bus.filter(new Func1<Object, Boolean>() { // @Override // public Boolean call(Object o) { // return eventType.isInstance(o); // } // }) .cast(eventType); } public static Subscription subscription(final String[] tags, final ResponseNode responseNode){ return getDefault().toObserverable(RxBusEvent.class) .filter(new Func1<RxBusEvent, Boolean>() { @Override public Boolean call(RxBusEvent rxBusEvent) { for(String tag : tags){ if(rxBusEvent.getTag().equals(tag)){ return true; } } return false; } }) .subscribe(new Action1<RxBusEvent>() { @Override public void call(final RxBusEvent rxBusEvent) { responseNode.operator(rxBusEvent);//开启职责链处理事件 } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { // TODO: 处理异常 Log.e("事件总线",throwable.toString()); } }); } }
新的HandlerFactory以下所示:app
package com.mitnick.root.mycample.util.rxbus.responslink; import android.content.Context; import android.util.Log; import java.lang.reflect.Method; import java.util.Map; /** * Created by root on 16-5-17. */ public class HandlerFactory { /** * 获得一个空的职责链处理节点 * @return responseNode 一个空的职责链处理节点 * */ public static ResponseNode getHandler(){ return new ResponseNode(new DoSomthing(null) { @Override public boolean dosomthing() { return false; } }); } /** * @param c 用于反射方法 * @param context 传入一个Activity用于回调方法 * @param events 须要分开处理的事件名称 * @return responseNode * * */ public static ResponseNode getHandler(final Class<?> c, final Context context, String[] events){ ResponseNode responseNode = getHandler(); ResponseNode buffer = responseNode; for(final String event : events){ buffer = buffer.setHandler(new ResponseNode(new DoSomthing(event) { @Override public boolean dosomthing() { try { Method method = c.getMethod(event); method.invoke(context); context.getClass().getMethod(event); } catch (Exception e) { e.printStackTrace(); Log.e("HandlerFactory",e.toString()); return filter(); } return filter(); } })); } buffer.setHandler(responseNode);//循环职责链 return responseNode; } /** * @param context 传入一个Activity用于回调方法 * @param events 须要分开处理的事件名称 * @return responseNode * * */ public static ResponseNode getHandler(final Context context, String[] events){ ResponseNode responseNode = getHandler(); ResponseNode buffer = responseNode; for(final String event : events){ buffer = buffer.setHandler(new ResponseNode(new DoSomthing(event) { @Override public boolean dosomthing() { try { Method method = context.getClass().getMethod(event); method.invoke(context); } catch (Exception e) { e.printStackTrace(); Log.e("HandlerFactory",e.toString()); return filter(); } return filter(); } })); } buffer.setHandler(responseNode);//循环职责链 return responseNode; } /** * @param context 传入一个Activity用于回调方法 * @param events 须要分开处理的事件名称 * @param eventMap 事件名称的一个转换,总线消息发送者无需知道接受者要回调哪一个函数来实现 * @return responseNode * */ public static ResponseNode getHandler(final Context context, String[] events, final Map<String, String> eventMap){ ResponseNode responseNode = getHandler(); ResponseNode buffer = responseNode; for(final String event : events){ buffer = buffer.setHandler(new ResponseNode(new DoSomthing(event) { @Override public boolean dosomthing() { try { String buffer = event; if(eventMap.containsKey(event)){ buffer = eventMap.get(event); } Method method = context.getClass().getMethod(buffer); method.invoke(context); } catch (Exception e) { e.printStackTrace(); Log.e("HandlerFactory",e.toString()); return filter(); } return filter(); } })); } buffer.setHandler(responseNode);//循环职责链 return responseNode; } }
下面来看一下如何注册事件:ide
//订阅事件总线并使用职责链处理 HashMap<String,String> reflact = new HashMap<>(); reflact.put("one","loginSuccess"); rxSubscription = RxBus.subscription( new String[]{"loginModel"}, HandlerFactory.getHandler( this, new String[]{"one", "loginFailed"}, reflact ) );
对,就是如此的简单!函数
基本原理是这样的,经过HandlerFactory得到职责链处理节点。HandlerFactory.getHandler的第一个参数是this,反射的回调须要用到this。第二个参数是一个String数组,这个数组的每个元素就是每个感兴趣的事件(能够有多个事件哦)。第三个参数是一个Map,是这样考虑的:由于我要实现高度的解耦,因此Model发送的每个事件都不会知道将会由谁来处理,可是在事件接受方须要将每个事件的每个动做(event)来经过反射映射到相应的处理函数(固然这一切都已经被HandlerFactory封装好了),因此须要用到这个Map来作一下映射,固然,若是event与处理函数同名,那么就只须要使用它的只有前两个参数的重载函数就能够了。post
固然,它也能够同时观察多个事件源,RxBus.subscription的第一个参数是一个String数组,它就是来存放事件源的。测试
下面再来看一下如何发送事件:this
RxBus.getDefault().post(new RxBusEvent("loginModel","one",null));
发送事件也是如此的简单!spa
下面来看一个具体的实现:
package com.mitnick.root.mycample; import android.app.ActivityOptions; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.transition.Explode; import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.mitnick.root.mycample.bean.user.User; import com.mitnick.root.mycample.util.rxbus.RxBus; import com.mitnick.root.mycample.util.rxbus.RxBusEvent; import com.mitnick.root.mycample.util.rxbus.responslink.HandlerFactory; import java.util.HashMap; import butterknife.Bind; import butterknife.ButterKnife; import me.james.biuedittext.BiuEditText; import rx.Subscription; public class LoginActivity extends AppCompatActivity implements View.OnClickListener { @Bind(R.id.userName) BiuEditText userName; @Bind(R.id.userPsw) BiuEditText userPsw; @Bind(R.id.login) Button login; @Bind(R.id.verify) TextView verify; @Bind(R.id.imageView3) ImageView baidu; @Bind(R.id.imageView2) ImageView weixin; @Bind(R.id.imageView) ImageView qq; @Bind(R.id.progressBar4) ProgressBar progress; private Subscription rxSubscription = null;//订阅RxBus事件 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 容许使用transitions getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); setContentView(R.layout.activity_login); ButterKnife.bind(this); } private void init() { setTitle("登陆"); login.setOnClickListener(this); verify.setOnClickListener(this); qq.setOnClickListener(this); weixin.setOnClickListener(this); baidu.setOnClickListener(this); // 设置一个exit transition getWindow().setExitTransition(new Explode());//new Slide() new Fade() //订阅事件总线并使用职责链处理 HashMap<String,String> reflact = new HashMap<>(); reflact.put("one","loginSuccess"); rxSubscription = RxBus.subscription( new String[]{"loginModel"}, HandlerFactory.getHandler( this, new String[]{"one", "loginFailed"}, reflact ) ); RxBus.getDefault().post(new RxBusEvent("loginModel","one",null)); } @Override protected void onResume() { super.onResume(); if(User.getInstence(null,null).isLogin()){ finish(); } init(); } @Override protected void onPause() { if(!rxSubscription.isUnsubscribed()){ rxSubscription.unsubscribe(); } super.onPause(); } @Override protected void onDestroy() { ButterKnife.unbind(this); super.onDestroy(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.login: login.setText(""); progress.setVisibility(View.VISIBLE); break; case R.id.imageView: break; case R.id.imageView2: break; case R.id.imageView3: break; } } public void loginSuccess(){ User.getInstence(userName.getText().toString(),userPsw.getText().toString()); startActivity(new Intent(LoginActivity.this, MainActivity.class), ActivityOptions.makeSceneTransitionAnimation(this).toBundle()); } public void loginFailed(){ login.setText("登陆"); progress.setVisibility(View.INVISIBLE); } }
在这个具体实现样例代码中,由于为了测试,我就在订阅了事件总线以后马上又本身向事件总线发送了一条事件。loginSuccess函数和loginFailed函数就是经过反射机制来回调的。