Start IntentService from Activity and refresh Activity when IntentService is finished

£可爱£侵袭症+ 提交于 2019-11-28 05:21:53

As an example, I use a ResultReceiver to call notifyDataSetChanged() on the adapter of my Activity (which extends ListActivity). It can be adapted to do whatever you need.

ResultReceiver code:

public class MyResultReceiver extends ResultReceiver {

    private Context context = null;

    protected void setParentContext (Context context) {
        this.context = context;
    }

    public MyResultReceiver(Handler handler) {
        super(handler);
    }

    @Override
    protected void onReceiveResult (int resultCode, Bundle resultData) {

        // Code to process resultData here

        ((BaseAdapter) ((ListActivity)context).getListAdapter()).notifyDataSetChanged();
    }
}

MyActivity code:

public class MyActivity extends ListActivity {

    private MyResultReceiver theReceiver = null;

    ...

    private void callService () {
        theReceiver = new MyResultReceiver(new Handler());
        theReceiver.setParentContext(this);
        Intent i = new Intent("com.mycompany.ACTION_DO_SOMETHING");

        // Code to define and initialize myData here

        i.putExtra("someData", myData);
        i.putExtra("resReceiver", theReceiver);
        startService(i);

    }
}

IntentService code:

Bundle resultBundle = new Bundle();
ResultReceiver resRec = intent.getParcelableExtra("resReceiver");

// Do some work then put some stuff in resultBundle here

resRec.send(12345, resultBundle);

When the IntentService completes, it should use LocalBroadcastManager to send an intent to any registered activity.

The IntentService will contain code like this:

private void sendBroadcast() {
    Intent intent = new Intent("myBroadcastIntent");
    intent.putExtra("someName", someValue);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

The activity receiving the notification will contain code like this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...
    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String someValue = intent.getStringExtra("someName");
            // ... do something ...
        }
    };
    LocalBroadcastManager.getInstance(this)
        .registerReceiver(receiver, new IntentFilter("myBroadcastIntent"));
}

For more depth, see the blog post Using LocalBroadcastManager In Service To Activity Communications.

None of the other answers references the official android documentation

https://developer.android.com/training/run-background-service/report-status.html

that states clearly that for the Activity-IntentService communication "The recommended way to send and receive status is to use a LocalBroadcastManager, which limits broadcast Intent objects to components in your own app"!

I would suggest using a Broadcast Receiver in the The Activity waiting for the result. Your Service would just use sendBroadcast with a custom Intent.

I think the event bus is the way to go. Simple and effective interprocess communication.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!