飙车资深老教练-手撸一个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
📢欢迎点赞👍收藏🌟留言📝
- 点赞
- 收藏
- 关注作者
评论(0)