stephanenicolas / robospice

Repo of the Open Source Android library : RoboSpice. RoboSpice is a modular android library that makes writing asynchronous long running tasks easy. It is specialized in network requests, supports caching and offers REST requests out-of-the box using extension modules.
Apache License 2.0
2.95k stars 545 forks source link

IllegalStateException #342

Closed ollie72 closed 10 years ago

ollie72 commented 10 years ago

In testing our app it crashed on one occasion with the exception below. Although it occurred within Robospice itself I'm unsure if this is a bug in RS or a result of something about the app itself.

Could it be relevant that the activity (Launcher) mentioned is an activity alias defined in the manifest (only)? The exception has only occurred once and I've not been able to re-create it at this stage.

java.lang.RuntimeException: Unable to stop activity {com.embarapp.android/com.embarapp.android.Launcher}: java.lang.IllegalStateException: Not started yet at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3278) at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3332) at android.app.ActivityThread.access$1200(ActivityThread.java:140) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4898) at java.lang.reflect.Method.invokeNative(Method.java) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773) at dalvik.system.NativeStart.main(NativeStart.java) Caused by: java.lang.IllegalStateException: Not started yet at com.octo.android.robospice.SpiceManager.shouldStopAndJoin(SpiceManager.java:316) at com.octo.android.robospice.SpiceManager.shouldStop(SpiceManager.java:299) at com.embarapp.android.RoboSpiceActivity.onStop(RoboSpiceActivity.java:20) at com.embarapp.android.GooglePlusActivity.onStop(GooglePlusActivity.java:43) at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1208) at android.app.Activity.performStop(Activity.java:5344) at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3273) at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3332) at android.app.ActivityThread.access$1200(ActivityThread.java:140) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4898) at java.lang.reflect.Method.invokeNative(Method.java) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773) at dalvik.system.NativeStart.main(NativeStart.java)

ollie72 commented 10 years ago

I looked at the exception in Robospice and I see it's a deliberately thrown exception if an attempt is made to stop the service when it's already running. I cannot see why this is happening as I'm just using the sample code provided in my base activity. The app does open two activities in quick succession sometimes so maybe it's a timing issue.

@Override
protected void onStop() {
    spiceManager.shouldStop();
    super.onStop();
}

I've wrapped it in a check to stop the exceptions which hopefully isn't covering up undesirable behaviour:

@Override
protected void onStop() {
    if (spiceManager.isStarted()) {
        spiceManager.shouldStop();
    }
    super.onStop();
}

I don't understand why if someone tries to stop the service when it's not running that the method has to throw an exception - why not just silently fail? But although I don't know why it's implemented this way, I expect it's by design rather than a bug.

stephanenicolas commented 10 years ago

Hi @ollie72, yes it is by design. My main motivation is that when implementing a state machine, even as simple as this, there is no reason to allow weird transition. As a developer I would expect and prefer to get an exception better than a silent fail that could hide other problems.

Btw, are you sure you don't use the same instance of spice manager elsewhere, likely in a fragment or through DI with a bad scope...

Stéphane