Android EventLine框架制作过程 四 Service与Activity、Fragment通讯

时间:2021-06-06 18:35:36

github项目代码地址,欢迎start

https://github.com/979451341/EventLine

这个系列文章的链接

Android 手动撸出一个事件总线框架 一 Activity上主线程的通信
http://blog.csdn.net/z979451341/article/details/79162303
 Android 手动撸出一个事件总线框架 二 Activity上主线程与子线程之间的通信
http://blog.csdn.net/z979451341/article/details/79164207
Android 手动撸出一个事件总线框架 三 Activity和Fragment之间的相互通信
http://blog.csdn.net/z979451341/article/details/79174626


这一次我们要解决四种情况:service发消息给Activity、Fragment,还有就是Activity、Fragment发消息给service



1.Service发消息给Activity、Fragment


为何这个两个要一起写呢,因为我发现原来写的代码就可以解决这个问题了,我贴出service代码

public class MyService extends Service {


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
DataBean dataBean = new DataBean();
dataBean.data = "来自MyService的消息";
EventLine.getInstance().postData(dataBean);
return super.onStartCommand(intent, flags, startId);
}

@Override
public IBinder onBind(Intent intent) {
return null;
}

}
触发发送消息
        btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent startIntent = new Intent(ThreeActivity.this, MyService.class);
startService(startIntent);

}
});
结果如下:
01-26 19:23:57.826 3204-3204/com.example.zth.eventline V/zzw: 在主线程MainFragment 接收到了来自MyService的消息
01-26 19:23:57.827 3204-3204/com.example.zth.eventline V/zzw: 在主线程MainActivity 接收到了来自MyService的消息
01-26 19:23:57.828 3204-3300/com.example.zth.eventline V/zzw: 在子线程TwoFragment 接收到了来自MyService的消息
01-26 19:23:57.829 3204-3301/com.example.zth.eventline V/zzw: 在子线程TwoActivity 接收到了来自MyService的消息

可以看出service发消息给Activity和Fragment没问题,但是反过来就不行了

2.Activity、Fragment发消息给Service

需要修改的只有发送消息的函数,加上对Service类型的处理

else if(object instanceof Service){

final Service service = (Service)object;
Class<? extends Service> cls = service.getClass();
try {
final Method declaredMethod = cls.getDeclaredMethod("receive", ojb.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) ojb);
} 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) ojb);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}).start();

}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}


}
然后在Service上的注册和注销和Activity、Fragment一样


public class MyService extends Service {


@Override
public void onCreate() {
super.onCreate();
EventLine.getInstance().add(this);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
DataBean dataBean = new DataBean();
dataBean.data = "来自MyService的消息";
EventLine.getInstance().postData(dataBean);
return super.onStartCommand(intent, flags, startId);
}

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onDestroy() {
EventLine.getInstance().remove(this);
super.onDestroy();
}

@Process(EventLine.MainThread)
public void receive(DataBean dataBean){
Log.v("zzw","在主线程MyService 接收到了"+dataBean.data);
}
}
然后在Activity和Fragment、Service都各发一条消息,
        DataBean dataBean = new DataBean();
dataBean.data = "来自MyService的消息";
EventLine.getInstance().postData(dataBean);
结果如下:
01-26 19:49:10.679 8004-8004/com.example.zth.eventline V/zzw: 在主线程MainFragment 接收到了来自ThreeActivity的消息
01-26 19:49:10.679 8004-8004/com.example.zth.eventline V/zzw: 在主线程MainActivity 接收到了来自ThreeActivity的消息
01-26 19:49:10.680 8004-8081/com.example.zth.eventline V/zzw: 在子线程TwoFragment 接收到了来自ThreeActivity的消息
01-26 19:49:10.681 8004-8082/com.example.zth.eventline V/zzw: 在子线程TwoActivity 接收到了来自ThreeActivity的消息
01-26 19:49:10.688 8004-8004/com.example.zth.eventline V/zzw: 在主线程MainFragment 接收到了来自MyService的消息
01-26 19:49:10.688 8004-8004/com.example.zth.eventline V/zzw: 在主线程MainActivity 接收到了来自MyService的消息
01-26 19:49:10.689 8004-8083/com.example.zth.eventline V/zzw: 在子线程TwoFragment 接收到了来自MyService的消息
01-26 19:49:10.690 8004-8004/com.example.zth.eventline V/zzw: 在主线程MyService 接收到了来自MyService的消息
01-26 19:49:10.690 8004-8084/com.example.zth.eventline V/zzw: 在子线程TwoActivity 接收到了来自MyService的消息
01-26 19:49:11.726 8004-8004/com.example.zth.eventline V/zzw: 在主线程MainFragment 接收到了来自ThreeFragment的消息
01-26 19:49:11.726 8004-8004/com.example.zth.eventline V/zzw: 在主线程MainActivity 接收到了来自ThreeFragment的消息
01-26 19:49:11.727 8004-8088/com.example.zth.eventline V/zzw: 在子线程TwoFragment 接收到了来自ThreeFragment的消息
01-26 19:49:11.727 8004-8004/com.example.zth.eventline V/zzw: 在主线程MyService 接收到了来自ThreeFragment的消息
01-26 19:49:11.727 8004-8089/com.example.zth.eventline V/zzw: 在子线程TwoActivity 接收到了来自ThreeFragment的消息
这样一来Activity、Fragment、Service算是实现了完全消息互通了

接下来我会来完善这个EventLine使它成为一个真正的框架,让大家一起来见证吧,

对了,这个系列的博客依旧会写,以后就写如何改善和扩展这个框架,大家有好点子可以发评论



完整的EventLline代码如下:
import android.app.Activity;
import android.app.Fragment;
import android.app.Service;
import android.util.Log;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
* Created by ZTH on 2018/1/25.
*/

public class EventLine<T> {


public static EventLine eventLine;

public final static int MainThread = 0;
public final static int SubThread = 1;

private EventLine(){

}

public static EventLine getInstance(){

if(eventLine == null){
synchronized (EventLine.class){
if(eventLine == null)
eventLine = new EventLine();
}
}
return eventLine;

}

private ArrayList<Object> objects = new ArrayList<Object>();

public void add(Object object){
objects.add(object);
}

public void remove(Object object){
objects.remove(object);
}



public void postData(final T ojb){

for(final Object object : objects){
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", ojb.getClass());
Annotation[] annotations = declaredMethod.getAnnotations();
for(Annotation annotation : annotations){
if(annotation.annotationType() == Process.class){
Process process = (Process)annotation;
value = process.value();

}
}


if(value == MainThread){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
declaredMethod.invoke(activity, (Object) ojb);
} 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) ojb);
} 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", ojb.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) ojb);
} 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) ojb);
} 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", ojb.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) ojb);
} 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) ojb);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}).start();

}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}


}


}

}

}
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Created by ZTH on 2018/1/25. */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Process {    int value() default 0;}