Как должен быть проинформирован фрагмент о результате асинхронной задачи?

У меня есть Activity, который использует фрагменты. Эти фрагменты могут приходить и уходить, основываясь на взаимодействиях пользователей. Многие из этих фрагментов запускают рабочие места в IntentService, которые запускают async таким образом. Как должен IntentService отчитываться о результатах этих заданий?

Фрагмент, который начал работу, может отсутствовать. Если задание завершается, и исходный фрагмент в настоящее время активен, он должен получить уведомление об этом и действовать соответствующим образом. Если это не так, никаких действий не требуется.

Я думал об использовании трансляции и компонентов BroadcastReceiver, но фрагменты не могут регистрировать приемники, а только действия.

Какое решение вы бы предложили?

Solutions Collecting From Web of "Как должен быть проинформирован фрагмент о результате асинхронной задачи?"

Я заметил ту же проблему в приложении IOSched ( приложение ввода / вывода Google для Android).

Они создали DetachableResultReceiver , который расширяет класс SDK класса ResultReciever .

И они легко используют его во Фрагментах .

Получатель:

/** * Proxy {@link ResultReceiver} that offers a listener interface that can be * detached. Useful for when sending callbacks to a {@link Service} where a * listening {@link Activity} can be swapped out during configuration changes. */ public class DetachableResultReceiver extends ResultReceiver { private static final String TAG = "DetachableResultReceiver"; private Receiver mReceiver; public DetachableResultReceiver(Handler handler) { super(handler); } public void clearReceiver() { mReceiver = null; } public void setReceiver(Receiver receiver) { mReceiver = receiver; } public interface Receiver { public void onReceiveResult(int resultCode, Bundle resultData); } @Override protected void onReceiveResult(int resultCode, Bundle resultData) { if (mReceiver != null) { mReceiver.onReceiveResult(resultCode, resultData); } else { Log.w(TAG, "Dropping result on floor for code " + resultCode + ": " + resultData.toString()); } } } 

Активность и фрагмент:

 public class HomeActivity extends BaseActivity { private static final String TAG = "HomeActivity"; private SyncStatusUpdaterFragment mSyncStatusUpdaterFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... mTagStreamFragment = (TagStreamFragment) fm.findFragmentById(R.id.fragment_tag_stream); mSyncStatusUpdaterFragment = (SyncStatusUpdaterFragment) fm .findFragmentByTag(SyncStatusUpdaterFragment.TAG); if (mSyncStatusUpdaterFragment == null) { mSyncStatusUpdaterFragment = new SyncStatusUpdaterFragment(); fm.beginTransaction().add(mSyncStatusUpdaterFragment, SyncStatusUpdaterFragment.TAG).commit(); triggerRefresh(); } } private void triggerRefresh() { final Intent intent = new Intent(Intent.ACTION_SYNC, null, this, SyncService.class); intent.putExtra(SyncService.EXTRA_STATUS_RECEIVER, mSyncStatusUpdaterFragment.mReceiver); startService(intent); if (mTagStreamFragment != null) { mTagStreamFragment.refresh(); } } /** * A non-UI fragment, retained across configuration changes, that updates its activity's UI * when sync status changes. */ public static class SyncStatusUpdaterFragment extends Fragment implements DetachableResultReceiver.Receiver { public static final String TAG = SyncStatusUpdaterFragment.class.getName(); private boolean mSyncing = false; private DetachableResultReceiver mReceiver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); mReceiver = new DetachableResultReceiver(new Handler()); mReceiver.setReceiver(this); } /** {@inheritDoc} */ public void onReceiveResult(int resultCode, Bundle resultData) { HomeActivity activity = (HomeActivity) getActivity(); if (activity == null) { return; } switch (resultCode) { case SyncService.STATUS_RUNNING: { mSyncing = true; break; } //... } activity.updateRefreshStatus(mSyncing); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ((HomeActivity) getActivity()).updateRefreshStatus(mSyncing); } } }