我能为Activity和Service之间的通信使用greenrobot EventBus吗?

23

EventBus这个库可以用来实现Activity到Service的通信吗?

我在我的应用程序中尝试了以下内容:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    EventBus.getDefault().register(this);
    setContentView(R.layout.activity_music_player);
    Intent serviceIntent=new Intent(MusicPlayerActivityTest.this,MusicPlayerServiceTest.class);
    startService(serviceIntent);
    EventBus.getDefault().post(new SetSongList(songArraList, 0));
}
@Override
protected void onDestroy() {
    EventBus.getDefault().unregister(this);
    super.onDestroy();
}

并且在我的服务中调用了onEvent


你在发布之前试过吗? - Mariano Zorrilla
1
是的,我尝试过了。但是出现了一个错误,说“订阅者类没有名为onEvent的公共方法”。 - Bincy Baby
你能解释一下如何使用它吗? - Bincy Baby
3
我看到您遇到错误,显示“Subscriber class has no public methods called onEvent”。除非您发布订阅者的代码,否则我们无法帮助您解决此问题。一般来说,您可以使用greenrobot的“EventBus”在服务和活动之间进行通信(反之亦然)。这里提供一个示例链接:https://github.com/commonsguy/cw-omnibus/tree/master/EventBus/GreenRobot。 - CommonsWare
但是 onEvent 没有调用服务。 - Bincy Baby
显示剩余2条评论
2个回答

30

你需要注册订阅者而不是发射器。

因此,如果您希望接收事件,则从您的应用程序中删除register/unregister。如果是这样,只需将onEvent(AnyEvent event)方法添加到Application类中。

然后在onStart()中在您的服务中注册EventBus,在onStop()中取消注册。

那应该会更好地工作。

在您的应用程序中

public class MyApp extend Application {
  @Override
  public void onCreate() {
    super.onCreate();
    ...
    EventBus.getDefault().post(new SetSongList(songArraList, 0));
  }
}

或者在您的活动中

public class MyActivity extend Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    EventBus.getDefault().post(new SetSongList(songArraList, 0));
  }
}

服务中的您

public class MyService extends Service {
  ...
  @Override
  public void onCreate() {
    super.onCreate();
    EventBus.getDefault().register(this);
  }

  @Override
  public void onDestroy() {
    EventBus.getDefault().unregister(this);
    super.onDestroy();
  }

  public void onEvent(SetSongList event){
    // do something with event
  }
  ...
}

8
应该是这样写 @Subscribe public void onEvent(SetSongList event){} 才对吧? - behelit
1
无论如何都不起作用,它产生了以下错误: 无法将事件分派到订阅类的服务类class someService中:class someEvent java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序。 - behelit
这是针对EventBus 2.4的,新版本3.0的API已经发生了变化。请在一个新线程中发布您的代码,以便我查看。 - Anthony
如果我想要实现相反的通信,从服务到活动,我该怎么做? - Rada Bogdan
2
只有当服务在同一进程中运行时,Activity -> Service 事件流才能正常工作。 - zyamys

5
在我的情况下,zyamys的评论有所帮助。同时,Anthony的答案是正确的,因为代码中有错误。
如果您使用不同的进程,则答案是否定的。如果使用不同的进程,这意味着它在不同的虚拟机上运行(例如Davlik)。所有静态字段都是不同的……!例如(AndroidManifest.xml):
<service android:name=".GPSTracker" android:process=":my_gps_tracker" />

如果您在相同的进程中运行服务,则答案是 。 示例(AndroidManifest.xml):

<service android:name=".GPSTracker"/>

在第一种情况下,我建议使用意图(Intents)与发送/接收广播功能结合使用来在服务和活动之间发送数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接