Downloading data using IntentService - Lifecycle changes

二次信任 提交于 2020-01-06 14:17:14

问题


Tl;dr How to know when an IntentService has finished downloading upon returning to the Activity which listens to its result using a BroadcastReceiver?


I'm moving to implementing data downloading to IntentServices, and notifying when the task has finished using BroadcastReceivers.

I generally start the service in my Activity:

IntentFilter intentFilter = DownloadDataService.startDownloadData(this);
getLocalBroadcastManager().registerReceiver(mBroadcastReceiver, intentFilter);

The part that starts the Service:

/**
 * Starts the service and returns an IntentFilter to subscribe a BroadcastReceiver on. 
 * When the task has finished, a broadcast for returned IntentFilter is sent,
 * containing downloaded data.
 */
public static IntentFilter startDownloadData(final Context context) {
    Intent intent = new Intent(context, DownloadDataService.class);
    intent.setAction(ACTION_DOWNLOAD_DATA);
    context.startService(intent);

    return new IntentFilter(ACTION_DOWNLOAD_DATA);
}

And of course, onHandleIntent(Intent) (simplified):

@Override
protected void onHandleIntent(final Intent intent){
    Data data = downloadData();
    Intent intent = new Intent(ACTION_DOWNLOAD_DATA);
    intent.putExtra(DATA, data);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

This all works well, and I can keep states in my Activity to know for example after an orientation change whether I was waiting for a download data result:

@Override
public void onResume(){
    super.onResume();
    if (mState == State.DOWNLOADING) {
        Log.v(TAG, "Registering receiver for existing download data");
        IntentFilter intentFilter = DownloadDataService.getIntentFilter();
        getLocalBroadcastManager().registerReceiver(mBroadcastReceiver, intentFilter);
    }
}

Great, now I can also handle orientation changes. Only one problem left:

  • Activity starts the DownloadDataService
  • User moves away from the Activity
  • DownloadDataService broadcasts its done message (which is not received by the Activity due to unregisterReceiver in onStop())
  • User moves back into the Activity
  • Activity still thinks it's waiting for the DownloadDataService, and does nothing.

How can I compensate for this?


Note that I do not have any persistence like databases for storing the downloaded data. The Activity retrieves the data from the broadcasted Intent.

Note #2: There is this answer to the question of how to know whether a Service is running. Although this might work, it is explicitly stated that that method is for debugging or implementing service management type user interfaces.


回答1:


use sendStickyBroadcast to send a sticky broadcast. This broadcast is held by the system.




回答2:


I wasn't really convinced by using SharedPreferences, static variables and other 'hacky' solutions.

I did find however that you can supply a ResultReceiver - which is parcelable - which you can use to notify your task is finished. It receives a Handler to specify the thread the result is handled on.

The advantage of this, is that you can save the ResultReceiver during onSaveInstanceState. Using some clever tricks you can certainly make this work. I have created an experimental library which facilitates this tactic: https://github.com/nhaarman/Ergo



来源:https://stackoverflow.com/questions/23363027/downloading-data-using-intentservice-lifecycle-changes

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