飙车资深老教练-手撸一个EventBus

举报
芝麻粒儿 发表于 2021/08/28 12:40:13 2021/08/28
【摘要】 👉关于作者众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣!!!专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)👉即将学会经过前面两节内容学习,我们已经学会了EventBus很多的内容,今天小空带你自己手撸一个这种...

👉关于作者

众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣!!!
专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)

👉即将学会

经过前面两节内容学习,我们已经学会了EventBus很多的内容,今天小空带你自己手撸一个这种框架。

👉背景

🙈小空(坏笑):小芝,昨天和前天的内容学习的怎么样啦。

🙎小芝(😝):还用说吗,肯定没学会啊。

🙈小空(😎):好,今天我们继续,直接自己写一个类似框架。

🙎小芝(😥):等等,我说的是没学会啊。啊?

👉实践过程

基本的反射调用

首先是事件总线的工具类,我们需要管理的有很多,所以有必要泛型一下

public static EventCar eventCar;
private EventCar() {
 
}
复制代码

单例完,就是add,remove等类似注册解注册的方法了,因为需要Activity/Fragment等类型,所以使用obj类型合适

private ArrayList<Object> objects = new ArrayList<Object>();
 
public void add(Object object){
    objects.add(object);
}
 
public void remove(Object object){
    objects.remove(object);
 
}
复制代码

这个时候基本的注册反注册就上线了,调用我们上面刚写的两个方法。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
    EventCar.getInstance().add(this);
}
 
@Override
protected void onDestroy() {
    EventCar.getInstance().remove(this);
    super.onDestroy();
}
复制代码

小关键来了,这个时候函数的反射调用要上了,因为不止Activity,所以我们要将里面分清楚

public void post(T obj) {
 
    for (Object object : objects) {  //在这区分了activity fragment等
 
        if (object instanceof Activity) {
            Activity activity= (Activity) object;
           Class<? extends Activity> cls =activity.getClass();
 
            try {
                Method declaredMethod = cls.getDeclaredMethod("receive", obj.getClass());  //""内的方法名之自定的
                declaredMethod.invoke(activity, (Object) obj);
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    }
}
复制代码

好了,我们小小的实验一下。看看能否出现效果

public void receive(MessageEvent msg) {
 
    Log.e("TAG","接受到了消息"+msg.getName());
}
 
@Override
protected void onDestroy() {
    EventCar.getInstance().remove(this);
    super.onDestroy();
}
 
@Override
public void onClick(View v) {
 
    switch (v.getId()) {
        default:
            break;
        case R.id.ceshi:
            EventCar.getInstance().post(new MessageEvent("空名先生"));
            break;
    }
}
复制代码

运行,结果出现

恩,效果可看,让我们继续的深入。

指定接收线程

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Process {
 
    int value() default 0;
 
}
复制代码

我们调用一下看看

@Process(EventCar.SubThread)  //内容在EventCar中有定义
 
public void receive(MessageEvent msg) {
    Log.e("TAG","接受到了消息"+msg.getName());
}
复制代码

回到EventCar中补全逻辑

final Method declaredMethod = cls.getDeclaredMethod("receive", obj.getClass());  //""内的方法名之自定的
Annotation[] annotations = declaredMethod.getAnnotations();
for(Annotation annotation : annotations){  //因为类可能不止一个标记 ,遍历获得对应的Process标记注解
    if(annotation.annotationType() == Process.class){
        Process process = (Process)annotation;
        value = process.value();
    }
} 
if(value == MainThread){
    activity.runOnUiThread(new Runnable() { //在ui线程
        @Override
        public void run() {
            try {
                declaredMethod.invoke(activity, (Object) obj);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    });
}else if(value == SubThread){
    new Thread(new Runnable() { //如果在子线程的话
        @Override
        public void run() {
            try {
                declaredMethod.invoke(activity, (Object) obj);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }).start();
}
复制代码

去测试下,咦,还是没问题;

好,满足了activity的 就该有fragment/activity/service各种交叉通信,这也是上面我们使用泛型和obj类型的原因

最终修补完善EventCar:

public void post(final T obj) {
    for (Object object : objects) {  //在这区分了activity fragment等
        int value = 0;
        if (object instanceof Activity) {
            final Activity activity = (Activity) object;
            Class<? extends Activity> cls = activity.getClass();
            try {
                final Method declaredMethod = cls.getDeclaredMethod("receive", obj.getClass());  //""内的方法名之自定的
                Annotation[] annotations = declaredMethod.getAnnotations();
                for (Annotation annotation : annotations) {  //因为类可能不止一个标记 ,遍历获得对应的Process标记注解
                    if (annotation.annotationType() == Process.class) {
                        Process process = (Process) annotation;
                        value = process.value();
                    }
                }
                if (value == MainThread) {
                    activity.runOnUiThread(new Runnable() { //在ui线程
                        @Override
                        public void run() {
                            try {
                                declaredMethod.invoke(activity, (Object) obj);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                               e.printStackTrace();
                            }
                        }
                    });
                } else if (value == SubThread) {
                    new Thread(new Runnable() { //如果在子线程的话
                        @Override
                        public void run() {
                            try {
                                declaredMethod.invoke(activity, (Object) obj);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    }).start();
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        } else if (object instanceof Fragment) {
            final Fragment fragment = (Fragment) object;
            Class<? extends Fragment> cls = fragment.getClass();
            try {
                final Method declaredMethod = cls.getDeclaredMethod("receive", obj.getClass());
                Annotation[] annotations = declaredMethod.getAnnotations();
                for (Annotation annotation : annotations) {
                    if (annotation.annotationType() == Process.class) {
                        Process process = (Process) annotation;
                        value = process.value();
                    }
                }
                if (value == MainThread) {
                    fragment.getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                declaredMethod.invoke(fragment, (Object) obj);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                } else if (value == SubThread) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                declaredMethod.invoke(fragment, (Object) obj);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    }).start();
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        } else if (object instanceof Service) {
            final Service service = (Service) object;
            Class<? extends Service> cls = service.getClass();
            try {
                final Method declaredMethod = cls.getDeclaredMethod("receive", obj.getClass());
                Annotation[] annotations = declaredMethod.getAnnotations();
                for (Annotation annotation : annotations) {
                    if (annotation.annotationType() == Process.class) {
                        Process process = (Process) annotation;
                        value = process.value();
                    }
                }
                if (value == MainThread) {
 
                    try {
                        declaredMethod.invoke(service, (Object) obj);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                } else if (value == SubThread) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                declaredMethod.invoke(service, (Object) obj);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    }).start();
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    }
}
复制代码

👉其他

📢作者:小空和小芝中的小空
📢转载说明:务必注明来源:https://zhima.blog.csdn.net/      https://juejin.cn/user/426576084
📢欢迎点赞👍收藏🌟留言📝

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。