源地址:https://blog.csdn.net/z979451341/article/details/79162303
一、基本的反射调用
首先是事件总线的工具类,我们需要管理的有很多,所以有必要泛型一下
public static EventCar eventCar;
private EventCar() {
}
//双重锁
public static EventCar getInstance() {
if (eventCar == null) {
synchronized (EventCar.class) {
if (eventCar == null) {
eventCar = new EventCar();
}
}
}
return eventCar;
}
单例完,就是add,remove等类似注册解注册的方法了,因为需要Activity/Fragment等类型,所以使用obj类型合适
private ArrayList
这个时候基本的注册反注册就上线了
@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 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 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 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 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();
}
}
}
}
拿着测试下,基本意思实现完毕;