public class MyEventBus {
private static MyEventBus instance = new MyEventBus();
private Map<Object, List<SubscribleMethod>> cacheMap;
private Handler mHandler;
private ExecutorService executorService;
private MyEventBus(){
cacheMap = new HashMap<>();
// 主進(jìn)程Handler
mHandler = new Handler(Looper.getMainLooper());
// 執(zhí)行子任務(wù)的線程池
executorService = Executors.newCachedThreadPool();
}
public static MyEventBus getDefault(){
return instance;
}
/**
* 注冊接收事件的類
* @param subscriber MainActivity
*/
public void register(Object subscriber){
Class<?> subscriberClass = subscriber.getClass();
List<SubscribleMethod> subscribleMethods = cacheMap.get(subscriberClass);
// 等于空就表示這個(gè)subscriber沒有注冊到cacheMap中
if(subscribleMethods == null){
subscribleMethods = getMethodsFromSubscriber(subscriber);
cacheMap.put(subscriber,subscribleMethods);
}
}
// 尋找訂閱者(MainActivity)中的訂閱方法福荸。即打了Subscrible注解的方法
private List<SubscribleMethod> getMethodsFromSubscriber(Object subscriber) {
List<SubscribleMethod> subscribleMethodList = new ArrayList<>();
Class<?> subscriberClass = subscriber.getClass();
// Eventbus也許是注冊在BaseActivity中的,所以要父類也需要遍歷液茎。
while (subscriberClass != null){
String name = subscriberClass.getName();
// BaseActiviy的父類是Activity逞姿,Activity肯定是不需要遍歷的,Activity的包名以Android.開頭捆等,所以遍歷到這里,就break
if(name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.") || name.startsWith("androidx.")){
break;
}
Method[] methods = subscriberClass.getDeclaredMethods();
// 尋找和 EventBus 相關(guān)的方法续室,并保存
for(int i = 0; i < methods.length; i++){
// EventBus語法栋烤,只能接收一個(gè)參數(shù)。
if(methods[i].getParameterTypes().length != 1){
continue;
}
// 必須要有 MySubscribe 注解挺狰,才是 EventBus 需要的方法
MySubscribe annotation = methods[i].getAnnotation(MySubscribe.class);
if(annotation == null){
continue;
}
MyThreadMode myThreadMode = annotation.threadMode();
Class<?> eventType = methods[i].getParameterTypes()[0]; // 只有一個(gè)參數(shù)明郭,所以獲取第0個(gè)位置上的數(shù)據(jù)
SubscribleMethod method = new SubscribleMethod(methods[i],myThreadMode,eventType);
// 將符合條件的方法保存到List集合中,并返回
subscribleMethodList.add(method);
}
subscriberClass = subscriberClass.getSuperclass();
}
return subscribleMethodList;
}
/**
* 發(fā)送事件
* @param event MessageEvent
*/
public void post(Object event){
Set<Object> keySet = cacheMap.keySet();
Iterator<Object> iterator = keySet.iterator();
// 遍歷所有的注冊類丰泊,在他們的注冊事件中尋找類型一樣的方法薯定,利用反射執(zhí)行這些方法
while(iterator.hasNext()){
// 注冊類 (MainActivity)
Object next = iterator.next();
List<SubscribleMethod> subscribleMethodList = cacheMap.get(next);
for(int i = 0; i < subscribleMethodList.size(); i++){
SubscribleMethod method = subscribleMethodList.get(i);
if(method.getEventType().isAssignableFrom(event.getClass())){
try{
invoke(method,next,event);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
// 使用反射執(zhí)行
private void invoke(final SubscribleMethod method,final Object next,final Object event) throws Exception{
// 注冊事件 指定的線程
try{
MyThreadMode threadMode = method.getThreadMode();
if(threadMode == MyThreadMode.MAIN){
// 發(fā)送事件如果是主線程
if(Looper.myLooper() == Looper.getMainLooper()){
// 主線程發(fā)送,主線程接收
method.getMethod().invoke(next,event);
}else{
// 發(fā)送事件是子線程瞳购,使用Handler發(fā)送消息
// 子線程發(fā)送话侄,主線程接收
mHandler.post(new Runnable(){
@Override
public void run() {
try{
method.getMethod().invoke(next,event);
}catch (Exception e){
e.printStackTrace();
}
}
});
}
}else if(threadMode == MyThreadMode.ASYNC){
if(Looper.myLooper() == Looper.getMainLooper()){
// 使用線程池,創(chuàng)建任務(wù)異步執(zhí)行
// 主線程發(fā)送学赛,子線程接收
executorService.execute(new Runnable() {
@Override
public void run() {
try{
method.getMethod().invoke(next,event);
}catch (Exception e){
e.printStackTrace();
}
}
});
}else {
// 子線程發(fā)送年堆,子線程接收
method.getMethod().invoke(next,event);
}
}else{
method.getMethod().invoke(next,event);
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 解除訂閱
*/
public void unregister(Object subscriber){
List<SubscribleMethod> subscribleMethodList = cacheMap.get(subscriber);
if(subscribleMethodList != null){
cacheMap.remove(subscriber);
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MySubscribe {
MyThreadMode threadMode() default MyThreadMode.POSTING;
}
// 注冊類中的注冊方法信息
public class SubscribleMethod {
// 注冊方法
private Method method;
// 線程類型
private MyThreadMode threadMode;
// 事件類型
private Class<?> eventType;
public SubscribleMethod(Method method, MyThreadMode threadMode, Class<?> eventType) {
this.method = method;
this.threadMode = threadMode;
this.eventType = eventType;
}
public Method getMethod() {
return method;
}
public MyThreadMode getThreadMode() {
return threadMode;
}
public Class<?> getEventType() {
return eventType;
}
}
public enum MyThreadMode {
// 誰發(fā)送的事件就在誰的線程中執(zhí)行
POSTING,
// 在主線程中執(zhí)行
MAIN,
// 在子線程中執(zhí)行
ASYNC
}
測試代碼
public class MainActivity extends AppCompatActivity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyEventBus.getDefault().register(this);
tv = findViewById(R.id.tv);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,MainActivity2.class);
MainActivity.this.startActivity(intent);
}
});
}
@MySubscribe(threadMode = MyThreadMode.MAIN)
public void get(MessageEvent event){
Log.e("xsl", event.getStr() );
tv.setText(event.getStr());
}
@Override
protected void onDestroy() {
super.onDestroy();
MyEventBus.getDefault().unregister(this);
}
}
public class MainActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
}
public void send(View view){
new Thread(new Runnable() {
@Override
public void run() {
MyEventBus.getDefault().post(new MessageEvent("我有一個(gè)小毛驢,我一直都不騎盏浇!"));
}
}).start();
}
}
結(jié)果
image.png
<https://github.com/xslandlr/AndroidStudy>
** MyEventBus **