Skip to content

Commit

Permalink
add unRegister
Browse files Browse the repository at this point in the history
  • Loading branch information
KingJA committed May 26, 2017
1 parent ee9b63c commit 0a3c42b
Show file tree
Hide file tree
Showing 10 changed files with 232 additions and 45 deletions.
10 changes: 10 additions & 0 deletions .idea/checkstyle-idea.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 12 additions & 13 deletions app/src/main/java/example/kingja/rxbus/FragmentA.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
Expand All @@ -11,6 +12,7 @@

import com.kingja.rxbus2.Callback;
import com.kingja.rxbus2.RxBus;
import com.kingja.rxbus2.Subscribe;

/**
* Description:TODO
Expand All @@ -27,7 +29,7 @@ public class FragmentA extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle
savedInstanceState) {

RxBus.getDefault().register(this);
rootView = inflater.inflate(R.layout.fragment_a, container, false);
return rootView;
}
Expand Down Expand Up @@ -70,17 +72,14 @@ public void onClick(View v) {
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
RxBus.getDefault().register(this, EventA.class, new Callback<EventA>() {
@Override
public void onReceive(EventA event) {
((TextView) rootView.findViewById(R.id.tv_eventMsg)).setText(event.getMsg());
}
});
RxBus.getDefault().register(this, EventC.class, new Callback<EventC>() {
@Override
public void onReceive(EventC event) {
((TextView) rootView.findViewById(R.id.tv_eventMsg)).setText(event.getMsg());
}
});

}
@Subscribe
public void receiveEventA(EventA event) {
((TextView) rootView.findViewById(R.id.tv_eventMsg)).setText(event.getMsg());
}
@Subscribe
public void receiveEventC(EventC event) {
((TextView) rootView.findViewById(R.id.tv_eventMsg)).setText(event.getMsg());
}
}
22 changes: 10 additions & 12 deletions app/src/main/java/example/kingja/rxbus/FragmentB.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import com.kingja.rxbus2.Callback;
import com.kingja.rxbus2.RxBus;
import com.kingja.rxbus2.Subscribe;

/**
* Description:TODO
Expand Down Expand Up @@ -50,17 +51,14 @@ public void onClick(View v) {
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
RxBus.getDefault().register(this, EventB.class, new Callback<EventB>() {
@Override
public void onReceive(EventB event) {
((TextView) rootView.findViewById(R.id.tv_eventMsg)).setText(event.getMsg());
}
});
RxBus.getDefault().register(this, EventC.class, new Callback<EventC>() {
@Override
public void onReceive(EventC event) {
((TextView) rootView.findViewById(R.id.tv_eventMsg)).setText(event.getMsg());
}
});
RxBus.getDefault().register(this);
}
@Subscribe
public void receiveEventB(EventB event) {
((TextView) rootView.findViewById(R.id.tv_eventMsg)).setText(event.getMsg());
}
@Subscribe
public void receiveEventC(EventC event) {
((TextView) rootView.findViewById(R.id.tv_eventMsg)).setText(event.getMsg());
}
}
14 changes: 7 additions & 7 deletions app/src/main/java/example/kingja/rxbus/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import com.kingja.rxbus2.Callback;
import com.kingja.rxbus2.RxBus;
import com.kingja.rxbus2.Subscribe;

public class MainActivity extends AppCompatActivity {
private final String TAG = getClass().getSimpleName();
Expand All @@ -24,13 +25,7 @@ protected void onCreate(Bundle savedInstanceState) {

getSupportFragmentManager().beginTransaction().add(R.id.fl_fragmentA, new FragmentA()).commit();
getSupportFragmentManager().beginTransaction().add(R.id.fl_fragmentB, new FragmentB()).commit();

RxBus.getDefault().register(this, EventMain.class, new Callback<EventMain>() {
@Override
public void onReceive(EventMain event) {
((TextView) findViewById(R.id.tv_main_eventMsg)).setText(event.getMsg());
}
});
RxBus.getDefault().register(this);
}

public void sendEventA(View view) {
Expand All @@ -45,4 +40,9 @@ public void sendEventC(View view) {
RxBus.getDefault().post(new EventC(this));
}

@Subscribe
public void receiveEventMain(EventMain event) {
((TextView) findViewById(R.id.tv_main_eventMsg)).setText(event.getMsg());
}

}
52 changes: 52 additions & 0 deletions rxbus2/src/main/java/com/kingja/rxbus2/MethodFinder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.kingja.rxbus2;

import android.util.Log;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* Description:TODO
* Create Time:2017/4/13 15:27
* Author:KingJA
* Email:kingjavip@gmail.com
*/
public class MethodFinder {
private static final int BRIDGE = 0x40;
private static final int SYNTHETIC = 0x1000;
private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();
private static final int MODIFIERS_IGNORE = Modifier.ABSTRACT | Modifier.STATIC | BRIDGE | SYNTHETIC;

public List<SubscriberMethod> findMehod(Class<?> subscriberClass) {
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
subscriberMethods = findByReflect(subscriberClass);
return subscriberMethods;
}

private List<SubscriberMethod> findByReflect(Class<?> subscriberClass) {
List<SubscriberMethod> subscriberMethods = new ArrayList<>();
Method[] methods = subscriberClass.getDeclaredMethods();
for (Method method : methods) {
int modifiers = method.getModifiers();
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
ThreadMode threadMode = subscribeAnnotation.threadMode();
Class<?> eventType = parameterTypes[0];
subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode));
}
}
}
}
return subscriberMethods;
}
}
71 changes: 58 additions & 13 deletions rxbus2/src/main/java/com/kingja/rxbus2/RxBus.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package com.kingja.rxbus2;

import android.content.Context;
import android.util.Log;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;

import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.processors.FlowableProcessor;
import io.reactivex.processors.PublishProcessor;
import io.reactivex.schedulers.Schedulers;

/**
* Description:TODO
Expand All @@ -26,13 +26,15 @@ public class RxBus {
private final FlowableProcessor<Object> mFlowableProcessor;
private static RxBus mRxBus;
private static Map<Class<?>, Map<Class<?>, Disposable>> mDisposableMap = new HashMap<>();
private final MethodFinder mMethodFinder;

/**
* Wraps this Subject and serializes the calls to the onSubscribe, onNext, onError and onComplete methods, making
* them thread-safe.
*/
private RxBus() {
mFlowableProcessor = PublishProcessor.create().toSerialized();
mMethodFinder = new MethodFinder();
}

public static RxBus getDefault() {
Expand All @@ -52,28 +54,71 @@ public void post(Object obj) {
}
}

public <T> void register(Object subscriber, Class<T> eventType, final Callback<T> callback) {
register(subscriber, eventType, callback, AndroidSchedulers.mainThread());
public void register(Object subsciber) {
Class<?> subsciberClass = subsciber.getClass();
List<SubscriberMethod> subscriberMethods = mMethodFinder.findMehod(subsciberClass);
for (SubscriberMethod subscriberMethod : subscriberMethods) {
addSubscriber(subsciber, subscriberMethod);
}
}

public <T> void register(Object subscriber, Class<T> eventType, final Callback<T> callback, Scheduler scheduler) {
Disposable disposable = mFlowableProcessor.ofType(eventType).observeOn(scheduler).subscribe(new Consumer<T>() {
private void addSubscriber(final Object subsciber, final SubscriberMethod subscriberMethod) {
Class<?> subsciberClass = subsciber.getClass();
Class<?> eventType = subscriberMethod.getEventType();
Scheduler threadMode = getThreadMode(subscriberMethod.getThreadMode());
Disposable disposable = mFlowableProcessor.ofType(eventType).observeOn(threadMode).subscribe(new Consumer<Object>() {
@Override
public void accept(T t) throws Exception {
callback.onReceive(t);
public void accept(Object o) throws Exception {
invokeMethod(subsciber, subscriberMethod, o);
}
});
Class<?> subscriberClass = subscriber.getClass();
Map<Class<?>, Disposable> disposableMap = mDisposableMap.get(subscriberClass);
Map<Class<?>, Disposable> disposableMap = mDisposableMap.get(subsciberClass);
if (disposableMap == null) {
disposableMap = new HashMap<>();
mDisposableMap.put(subscriberClass, disposableMap);
mDisposableMap.put(subsciberClass, disposableMap);
}
disposableMap.put(eventType, disposable);
}

public void unRegister(Object subscriber, Class<?> eventType) {
private Scheduler getThreadMode(ThreadMode threadMode) {
Scheduler scheduler;
switch (threadMode) {
case MAIN:
scheduler = AndroidSchedulers.mainThread();
break;
case IO:
scheduler = Schedulers.io();
break;
case COMPUTATION:
scheduler = Schedulers.computation();
break;
case SINGLE:
scheduler = Schedulers.single();
break;
case TRAMPOLINE:
scheduler = Schedulers.trampoline();
break;
case NEW_THREAD:
scheduler = Schedulers.newThread();
break;
default:
scheduler = AndroidSchedulers.mainThread();
break;
}
return scheduler;
}

private void invokeMethod(Object subsciber, SubscriberMethod subscriberMethod, Object obj) {
try {
subscriberMethod.method.invoke(subsciber, obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}

public void unRegister(Object subscriber, Class<?> eventType) {
Class<?> subscriberClass = subscriber.getClass();
Map<Class<?>, Disposable> disposableMap = mDisposableMap.get(subscriberClass);
if (disposableMap == null) {
Expand Down
20 changes: 20 additions & 0 deletions rxbus2/src/main/java/com/kingja/rxbus2/Subscribe.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.kingja.rxbus2;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Description:TODO
* Create Time:2017/5/26 14:40
* Author:KingJA
* Email:kingjavip@gmail.com
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
ThreadMode threadMode() default ThreadMode.MAIN;
}
33 changes: 33 additions & 0 deletions rxbus2/src/main/java/com/kingja/rxbus2/SubscriberMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.kingja.rxbus2;

import java.lang.reflect.Method;

/**
* Description:TODO
* Create Time:2017/4/13 15:28
* Author:KingJA
* Email:kingjavip@gmail.com
*/
public class SubscriberMethod {
public ThreadMode getThreadMode() {
return threadMode;
}

final ThreadMode threadMode;
final Method method;
final Class<?> eventType;

public SubscriberMethod(Method method, Class<?> eventType,ThreadMode threadMode) {
this.method = method;
this.eventType = eventType;
this.threadMode = threadMode;
}

public Method getMethod() {
return method;
}

public Class<?> getEventType() {
return eventType;
}
}
17 changes: 17 additions & 0 deletions rxbus2/src/main/java/com/kingja/rxbus2/Subscription.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.kingja.rxbus2;

/**
* Description:TODO
* Create Time:2017/4/13 15:56
* Author:KingJA
* Email:kingjavip@gmail.com
*/
public class Subscription {
final Object subscriber;
final SubscriberMethod subscriberMethod;

Subscription(Object subscriber, SubscriberMethod subscriberMethod) {
this.subscriber = subscriber;
this.subscriberMethod = subscriberMethod;
}
}
13 changes: 13 additions & 0 deletions rxbus2/src/main/java/com/kingja/rxbus2/ThreadMode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.kingja.rxbus2;

import io.reactivex.Scheduler;

/**
* Description:TODO
* Create Time:2017/5/26 14:47
* Author:KingJA
* Email:kingjavip@gmail.com
*/
public enum ThreadMode {
SINGLE, COMPUTATION, IO, TRAMPOLINE, NEW_THREAD,MAIN
}

0 comments on commit 0a3c42b

Please sign in to comment.