Espere con la operación hasta que se creen Vistas de fragmentos

Estoy programando un reproductor de música y la música se reproduce en un Service fondo. Cuando el usuario elimina la Activity que aloja 3 Fragments y vuelve a iniciar la Activity , envío una Broadcast del Service que contiene información sobre la canción actual y la lista de canciones que el usuario agregó a su sesión.

El problema es que cada vez que quiero configurar la última información en los Fragments no ocurre nada porque su creación tarda demasiado, y la Broadcast no se maneja como deberían.

¿Cómo puedo dejar que el Service o la Broadcast esperen hasta que se creen los Fragmentos para que se manejen adecuadamente?

Aquí están los fragmentos de código relevantes:

 //When the activity binds to the service, refresh the fragments private ServiceConnection conn = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { LocalBinder binder = (LocalBinder) service; myService = binder.getService(); myService.setBound(true); if(myService.startedOnce) { myService.refreshFragments(); } myService.startedOnce = true; } } //This is the broadcast receiver of the Fragment //it receives the broadcast too soon, and I can't set the //Views so they are always empty. public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(MusicService.REFRESH_ALL)) { Song current = intent.getParcelableExtra("song"); setCurrentSong(current); } } 

Lo más fácil de hacer sería simplemente mantener la información hasta que el fragmento esté listo para mostrarla. Utilice el método setArguments() del Fragmento para adjuntar la información al Fragmento.

 @Override public void onReceive() { String action = intent.getAction(); if(action.equals(MusicService.REFRESH_ALL)) { // Creating a new Bundle so the Fragment can control its own object Bundle args = new Bundle(intent.getExtras()); Fragment fr = getUsingFragment(); fr.setArguments(fr); } } 

Entonces, en el fragmento onCreateView() simplemente tire de los argumentos de getArguments() y construya la vista con los valores.

 @Override public void onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Bundle args = getArguments(); if(args != null) { // code to set values if arguments are set } else { // code to set values if arguments are not set } } 

Otra forma de hacerlo sería utilizar métodos setter en los que el Fragmento pone valores en un Bundle para setArguments() . De esta forma, puede actualizar las vistas siempre que se haya creado la Vista encima de la configuración de los argumentos para el posible evento cuando se destruya la vista del fragmento y se debe volver a crear.

Nota: Sólo puede llamar a setArguments() antes de que el Fragmento se haya adjuntado a la Actividad. Sin embargo, puede actualizar el paquete que pasa por setArguments recuperando una referencia a él desde getArguments() , simplemente poniendo los valores. Así que en lugar de llamar a setArguments() de su receptor, haga algo como esto:

 public void setCurrentSong(Song extra) { Bundle args = getArguments(); args.putParcable(KEY_MAP, extra); if(/* Views are created */) { // update and invalidate the views } } 

Cómo arreglé esto

Como estaba usando un servicio para la reproducción de medios, quería sacar las últimas canciones escuchadas del servicio para poder reproducirlas directamente. Esta era vieja lógica, pero construí realmente mi código alrededor de ella. Hasta entonces, me topé con él.

Esto estaba pasando

  • FragmentActivity crea FragmentActivity
  • Service se inicia y se enlaza con
  • Mientras tanto, los Fragments se crean asincrónicamente
  • Tan pronto como el Service inicia, envía una Broadcast con la información más reciente
  • Debido a que las creaciones de Service y Fragment son asíncronas, la difusión se enviaría desde el servicio, pero como los BroadcastReceivers de los Fragments no fueron inicializados aún, no recibirían el Intent .

Lo que hice para arreglarlo

De alguna manera tuve que usar una devolución de llamada que se aseguró de que

  • El Servicio fue creado y obligado a
  • Los fragmentos creados y las vistas se establecen

Así que utilicé el ServiceConnection y para ser exactos, el método onServiceConnected() . Allí obtuve las preferencias en las que se guardó la última canción y luego envié la Broadcast y los Fragments recibieron y las Views fueron ajustadas apropiadamente. Esto también funcionó para los cambios de orientación.

El código

 //This is the code in the FragmentActivity private ServiceConnection conn = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { LocalBinder binder = (LocalBinder) service; myService = binder.getService(); myService.setBound(true); if (myService.startedOnce) { myService.refreshFragments(); } else { sendLastSavedSong(); } myService.startedOnce = true; } public void onServiceDisconnected(ComponentName className) { myService.setBound(false); } }; 

¿No puedes hacer algo en el fragmento como

 Song current=null; public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(MusicService.REFRESH_ALL)) { current = intent.getParcelableExtra("song"); } } @Override public void onResume() { if(current!=null) setCurrentSong(current); super.onResume(); } 

Mi solución sólo estaba creando sus propias interfaces de devolución de llamada. Al final del método onCreateView de ur fragmento basta con llamar a su método de devolución de llamada, que le dice ur mainactivity que la creación se hace.

Funcionó para mí, la esperanza también te ayuda.

  • Utilizando IntentService para la reproducción de MediaPlayer
  • Vibrar en la notificación push
  • El proceso del servicio se cancela después de que la aplicación se elimina de la bandeja de aplicaciones
  • Relación de actividad y servicio de Android: después de Pausa, después de Parar
  • ¿Qué es un JobService en Android?
  • ¿Es correcto llamar a Service.startService () desde Service.onBind ()?
  • Android: Enviar correo electrónico con datos adjuntos automáticamente en segundo plano
  • Problemas con la vinculación al servicio en Android
  • Aplicación de Android Service
  • ¿Cómo registrar un servicio de reconocimiento de voz personalizado?
  • Cómo detener un servicio de Android desde un hilo
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.