¿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.
- Establecer un subtítulo en mi barra de herramientas de un fragmento
- Problema extraño que refresca ViewPager con nuevo contenido:
- OnActivityResult no está siendo llamado en Fragment
- Android - NullPointerException desde la creación de un adaptador
- Valor de restablecimiento de un entero a una hora específica del día
He pensado en usar intentos de difusión y componentes BroadcastReceiver, pero los fragmentos no pueden registrar receptores, solo actividades.
¿Qué solución sugiere?
- ActionBarActivity requestFeature se debe llamar antes de agregar contenido
- Búsqueda de Android con Fragmentos
- Restaurar el estado del widget de vista de búsqueda de android
- Obtener el fragmento visualizado actualmente
- Creación de un fragmento en una ventana emergente - en Android
- Anular el oyente en Fragment onDetach ()?
- .getSupportActionBar no está disponible en Fragment; La solución lleva a NullPointerException en rotación
- Listener para el ciclo de vida de los fragmentos
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); } } }
- Vistas circulares personalizadas
- Evitar la pérdida de datos debido a la interrupción al guardar archivos en android?