Search code examples
androidrobospice

Robospice Android - spiceRequest that begins in one activity and ends in another activity


I'm trying to start a robospice request in Activity A and then receive the results of the request in Activity B.

In Activity A

FetchSpiceRequest fetchSpiceRequest = new FetchSpiceRequest();
spiceManager.execute(fetchSpiceRequest, new ActivityB().postListener);

The PostListener implements PendingRequestListener and is sitting within Activity B.

In Activity B

We addListener for the pending request that was started in Activity A below.

@Override
protected void onStart() {
    spiceManager.start( this );
    spiceManager.addListenerIfPending(Post.class, 0, new PostListener());

We then implement the PostListener in Activity B below.

public final class PostListener implements PendingRequestListener<Post> {

    @Override
    public void onRequestFailure(SpiceException spiceException) {
        Toast.makeText(MainActivity.this, "Exception: " + spiceException.toString(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onRequestSuccess(Post post) {
        Toast.makeText(MainActivity.this, "Added", Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onRequestNotFound() {
        Toast.makeText(MainActivity.this, "Request not found", Toast.LENGTH_SHORT).show();
    }
}

Finally, we create a variable within Activity B called so that A can pick it up (eg. when I call new ActivityB().postListener):

public PostListener PostListener;

This doesn't work and it always calls onRequestNotFound in the PostListener.

What am I doing wrong?

I have also looked at this post: Robospice - keep spice service continue running when changing activity but @Snicolas doesn't seem to mention anything about how the spiceManager.execute statement should look like in the first activity.


Solution

  • Eventually, I had to use LocalBroadcastManager to achieve what I want to do:

    Activity A

    FetchSpiceRequest fetchSpiceRequest = new FetchSpiceRequest();
    spiceManager.execute(fetchSpiceRequest, postListener);
    

    Please note that postListener is situated within Activity A. It actually doesn't do much as all the work will now be performed inside the localbroadcastreceiver:

    public final class AddPostListener implements RequestListener<Post> {
    
        @Override
        public void onRequestFailure(SpiceException spiceException) {
            Toast.makeText(AddPostActivity.this, "Exception: " + spiceException.toString(), Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onRequestSuccess(Post post) {
            Toast.makeText(AddPostActivity.this, "Added", Toast.LENGTH_SHORT).show();
            Log.e("AddPostListener", "Background service finished"); }
    

    Inside the fetchSpiceRequest, we perform the work asynchronously and once it is finished, we call the localbroadcast manager to send our results back to Activity B:

    public class FetchSpiceRequest extends SpringAndroidSpiceRequest<Post> {
    
        private Post mPost;
        private Context mContext;
    
        public AddPostSpiceRequest(Context context, Post post) {
            super(Post.class);
            mPost = post;
            mContext = context;
        }
    
        @Override
        public Post loadDataFromNetwork() throws Exception {
    //Do some network activity to get a post and then after the network activity ends, send the post through the broadcast activity to Activity B
            Intent intent = new Intent("my-event");
            intent.putExtra("post", post);
            LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);   
    }
    

    Activity B

    Register your localBroadcast receiver:

    @Override
    public void onResume() {
        super.onResume();
        LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
                new IntentFilter("my-event")); }
    

    Do something with the received message:

    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // Get extra data included in the Intent
            Post post = intent.getParcelableExtra("post");
            Log.e("receiver", "Got message: " + post.getPostheader());
        }
    };