Robospice - keep spice service continue running when changing activity
Asked Answered
M

2

8

I used RoboSpice library to do asynchronous tasks. From their examples, the spice service is declared in BaseActivity, it starts in activity's onStart method, and stops in activity's onStop. Everything is fine, but when I want download file from internet, and then I change to another activity, this download task is cancelled, because the spice service is stopped. It looks like:

public abstract class BaseActivity{
  /** The request manager. */
private SpiceManager requestManager = new SpiceManager(RequestService.class);   
  @Override
   protected void onStart() {   
      requestManager.start(this);
      super.onStart();     

   }

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

So I wonder is there any safe way to keep the download task continue running from Spice service (this task doesn't touch UI), and another tasks work normally (mean they can be cancelled when stop activity) but it still can respect the activity life circle.

Malchus answered 8/11, 2013 at 15:20 Comment(0)
S
11

@R4j, you missed the point. Requests are not stopped when the activity holding the spicemanager stops. In RS, requests will have their own lifecycle and will be exectued in a different context (a spice service that is an Android Service).

Thus, if you fire a request, then your activity dies or gets killed, the spice request will go on its own way and download will continue. Parsing will occur as well, and finally your result will be placed in the cache. If any.

So if you want to trigger a request in activity A and get the result in activity B, you should :

  • simply execute the request in activity A as usual, follow RS samples
  • in B, after starting your spiceManager (i.e. right after super.onStart()), do 2 things :

    • use spiceManager.addListenerIfPending to replug the new activity on any pending request
    • use spiceManager.getDataFromCache to get any result that could already have been put in the cache by a previous request
  • optionnally, if you want to re-execute the request in B itself, you can, and you will be happy to learn that if you use the same request class with the same cache key, RS will aggregate your new request to any pending request for you.

In RS, a request is identified by a compound key made of "class of result of a request" + "request cache". This compound key can be used to retrieve a pending request as well as any result put by this request in the cache.

Sirotek answered 12/11, 2013 at 6:8 Comment(4)
So I have to use cache for my request to keep it alive between activities? How about 's the request without caching?Malchus
Without caching, you could still re-plug to a pending request using addListenerIfPending or execute. The former only plug a listener if a request is pending, the second does that and triggers a request if none is pending.Sirotek
sorry, could you give me an example re-plug without caching? I tried a cache request and it worked, but for the non-cache request, addListenerIfPending not work for me now.Malchus
The simpler in that case, and you are right I was not clear at all, is to use both a cache key and cache expiry inside execute. But use a SpiceService with no cache, like UncachedSpiceServiceSirotek
L
2

Declate a spicemanager instance in your application class and access it in activity to start background service.

public class MyApplication extends Application {

    private static MyApplication instance;
        private SpiceManager spiceManager = new SpiceManager(RequestService.class);

    @Override
    public void onCreate() {
        super.onCreate();
    }


    public SpiceManager getManager()
    {
       return spiceManager;
    }

}

In Activity, you can call it. See my code below.

((MyApplication) getApplicationContext()).getSpiceManager().startService(........);
Lineation answered 8/11, 2013 at 15:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.