3

I have the launcher activity in my app that should fire an event with otto event bus in onCreate(). The activity itself makes sure that a service is started. The bus is implemented as a singleton via a BusProvider of a derived class of the bus. Whenever I post to the bus from my activity, the activity itself receives the event (I subscribed for debugging purposes) but not the service, although it should both be sent on the main thread.

Because I receive the event in the activity, otto basically seams to work. I assume that the difference between service (background) and activity (ui) may be the cause why I don't receive the event in the service, but why?

Here is the code of My derived Bus Class:

public class MainBus extends Bus {
    private final Handler handler = new Handler(Looper.getMainLooper());

    public MainBus(ThreadEnforcer any) {
        super(any);
    }

    @Override
    public void post(final Object event) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            super.post(event);
        } else {
            handler.post(new Runnable() {
                @Override
                    public void run() {
                        MainBus.super.post(event);
                }
            });
        }
    }
}   

Here is the BusProvider Singleton

public final class BusProvider {
    // Also tried with ThreadEnforcer.MAIN 
    private static final MainBus BUS = new MainBus(ThreadEnforcer.ANY);

    public static MainBus getInstance() {
        return BUS;
    }

    private BusProvider() {
        // No instances.
    }
}

Here is the relevant code of my Activity

public class Splashscreen extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        BusProvider.getInstance().register(this);

        // Start the Service if not yet started.
        if (!isMyServiceRunning()) {
            startMyService();
        }

        LogProvider.getInstance().d("Splashscreen", "Activity started.");
        BusProvider.getInstance().post(new SplashscreenStartupCompletedEvent());
        LogProvider.getInstance().d("Splashscreen",
                "After Startup Event posted");

        setContentView(R.layout.splashscreen);
    }

    /**
     * private function to check if the service is running
     * 
     * @return boolean True if the service is running, false otherwise
     */
    private boolean isMyServiceRunning() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager
                .getRunningServices(Integer.MAX_VALUE)) {
            if (MyApplicationService.class.getName().equals(
                    service.service.getClassName())) {
                LogProvider.getInstance().i("Splashscreen",
                        "Service is already running.");
                return true;
            }
        }
        LogProvider.getInstance().n("Splashscreen", "Service is not running.");
        return false;
    }

    /**
     * private function to start the Backgroundservice
     */
    private void startMyService() {
        LogProvider.getInstance().i("Splashscreen", "Service will be started.");
        Context context = getApplicationContext();
        Intent service = new Intent(
                context,
                com.classpath.MyApplicationService.class);
        context.startService(service);
    }

    @Subscribe
    public void afterStartEvent(SplashscreenStartupCompletedEvent event) {
        LogProvider.getInstance().d("afterStartEvent", "Event received");
    }
}

And the relevant part of the Service

public class MyApplicationService extends Service {
    @Override
    public void onCreate() {
        BusProvider.getInstance().register(this);       
        super.onCreate();
    }

    @Subscribe
    public void afterStartupCompleted(SplashscreenStartupCompletedEvent event) {
        LogProvider.getInstance().d("MyApplicationService",
                "StartupCompletedEvent empfangen");
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }
}
McGo
  • 3,792
  • 2
  • 13
  • 18
  • I narrowed it down a bit with subscribers and publisher on Service, Application and Activity: - Posting an event from activity makes it available on the application and the Activity NOT the Service. - Posting an event from service makes it available on the application, the activity AND the service. And that is something I don't understand- – McGo Jan 14 '15 at 10:56

0 Answers0