¿Cómo debe notificarse un fragmento sobre el resultado de una tarea asíncrona?

Tengo una Actividad que usa fragmentos. Estos fragmentos pueden ir y venir, basados ​​en las interacciones de los usuarios. Muchos de estos fragmentos lanzan trabajos a un IntentService, que consigue funcionar async de esta manera. ¿Cómo debe el informe IntentService devolver los resultados de estos trabajos?

El fragmento que inició el trabajo puede no estar presente. Si un trabajo termina y el fragmento de inicio está activo, entonces debería recibir notificación sobre esto y actuar en consecuencia. Si no es así, entonces no se necesita ninguna acción.

He pensado en usar intentos de difusión y componentes BroadcastReceiver, pero los fragmentos no pueden registrar receptores, solo actividades.

¿Qué solución sugiere?

Me di cuenta del mismo problema en la aplicación IOSched (Google I / O App para Android).

Ellos crearon DetachableResultReceiver , que extiende SDK clase ResultReciever .

Y lo usan fácilmente en Fragmentos .

Receptor:

/** * 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()); } } } 

Actividad y Fragmento:

 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); } } } 
  • Actualizar el fragmento cuando se desactiva el diálogo
  • No se puede usar barra de acción y Fragmento en Android 2.3
  • ¿Por qué se llama onAttach antes de onCreate?
  • Fragmento de Android pop de backstack con animación
  • Android con intención de abrir un fragmento de una actividad
  • Duplicar ID con Fragmento en la página PagerAdapter
  • Lista de retención en el fragmento de lista sobre el cambio de orientación
  • ID duplicado con fragmento
  • Acceso a TextView en ViewPager desde la actividad
  • El fragmento ViewPager no funciona en la segunda vez dentro del fragmento del cajón de navegación correctamente
  • OnActivityResult () no llamado cuando la actividad se inició desde el fragmento
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.