2012-06-07 19 views
5

Estoy implementando un cliente REST en Android. He visto un ejemplo de usar un Service para realizar la conexión al servidor y el ResultReceiver para recibir notificación de la finalización de la operación. Estoy llamando al servicio desde un fragmento y, si trato de rotar la pantalla mientras el servicio se está ejecutando, el método getActivity() en ResultReceiver devuelve nulo porque probablemente ese fragmento ya no está en el diseño.ResultReceiver no supera la rotación de pantalla

El método de devolución de llamada en el fragmento:

@Override 
public void onReceiveResult(int resultCode, Bundle resultData) { 
    Response response = (Response) resultData 
      .getSerializable(RestService.RESULT); 
    if (resultCode == RestService.SUCCESS 
      && response != null) { 
     if (getActivity() != null) { 
      recommendationResponse = response; 
      getLoaderManager().restartLoader(0, new Bundle(), 
        Fragment.this); 
     } 

    } 
} 

Los getActivity() devuelve null. ¿Es esto normal? ¿Qué enfoque podría usar para permitir la notificación incluso en la rotación de la pantalla? Transmisión local?

Respuesta

1

estoy usando un BroadcastReceiver registrado utilizando LocalBroadcastManager y está trabajando correctamente. No fue tan simple. ¿Existe una mejor solución?

-1

La getActivity() devuelve null. ¿Esto es normal?

Actividades Android se recrean después de la rotación del dispositivo.

Después se vuelve a crear la actividad que no sostiene antiguo de context.that por qué su conseguir getActivity() como nulo

¿Qué enfoque podría utilizar para permitir la notificación en la pantalla incluso rotación? Transmisión local?

Si no quieres que la actividad recreado en rotation.mention siguiente pantalla en el manifiesto

 <activity 
      android:name=".MyActivity" 
      android:configChanges="orientation" <<<<<<<<< 
      android:label="@string/app_name" 
      android:screenOrientation="portrait" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

Y por último, usted tendrá que reemplazar siguiente en la actividad.

@Override 
    public void onConfigurationChanged(Configuration newConfig) 
    { 
     // TODO Auto-generated method stub 
     super.onConfigurationChanged(newConfig); 
    } 
+2

Gracias por la respuesta. En realidad, preferiría no configurar la propiedad screenOrientation en el manifiesto porque el diseño es diferente en el modo horizontal, por lo que no puedo configurarlo. – Matroska

1

Creo que tropecé con el mismo problema y lo resolví al verificar NULL en el método onReceivedResult de mi ResultReceiver. El código publicado aquí trabaja en un fragmento del trabajador (fragmento sin interfaz de usuario y setRetainInstance (verdadero) en onCreate)

protected void onReceiveResult(int resultCode, Bundle resultData) { 
      //Verify activity 
      if(getActivity() != null){ 
       //Handle result 
      }else{ 
       notificationPending = true;     
      } 
     } 

Las banderas notificationPending ayuda a que el fragmento de sostener la notificación pendiente que no se halló la actividad (actividad no está disponible en fragmento Detach).

Cuando el fragmento se vuelve a unir a la actividad que realizo esta lógica

public void onAttach(Activity activity){ 
    super.onAttach(activity); 
     if(notificationPending){ 
      //Handle notification 
      notificationPending = false; 
     } 
} 

espero que ayude. Puede solicitar más detalles si lo desea. Saludos

12

No,

android:configChanges="orientation" 

no es una solución.

Para utilizar ResultReceiver I:

  • guardarla en cambios de orientación:

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
        outState.putParcelable(Consts.RECEIVER, mReceiver); 
        super.onSaveInstanceState(outState); 
    } 
    
  • restablecer el receptor:

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) { 
    
        if (savedInstanceState != null) { 
         mReceiver = savedInstanceState.getParcelable(Consts.RECEIVER); 
        } 
        else { 
         mReceiver = new MyResultReceiver(new Handler()); 
        } 
        mReceiver.setReceiver(this); 
    } 
    

Aquí es mi clase ResultReceiver:

import android.os.Bundle; 
import android.os.Handler; 
import android.os.ResultReceiver; 

public class MyResultReceiver extends ResultReceiver { 
    private Receiver mReceiver; 

    public MyResultReceiver(Handler handler) { 
     super(handler); 
    } 

    public void setReceiver(Receiver receiver) { 
     mReceiver = receiver; 
    } 

    public interface Receiver { 
     public void onReceiveResult(int command, Bundle resultData); 
    } 

    @Override 
    protected void onReceiveResult(int command, Bundle resultData) { 
     if (mReceiver != null) { 
      mReceiver.onReceiveResult(command, resultData); 
     } 
    } 
} 
+0

¡Brillante! Vi muchas otras preguntas similares (con muchos votos ascendentes) relacionadas con [ResultReceiver] (http://developer.android.com/reference/android/os/ResultReceiver.html), y cualquiera de ellas abordaba con éxito un escenario tan frecuente como actividad recreación. – villoren

+0

¿Cómo se evita una ClassCastException en onCreateView() al llamar a getParcelable()? ¿GetParcelable() no devuelve una instancia de ResultReceiver (no una instancia de su subclase) porque su subclase no implementa Parcelable.CREATOR? – Alan

+0

@ Alan Con mi prueba, cuando gira el dispositivo, el método anterior funciona. Sin embargo, si android apaga la aplicación en segundo plano y la vuelve a iniciar, obtengo ClassCastException en onCreateView(). No estoy seguro por qué pero esto es lo que encontré en mis pruebas ... – Micro

Cuestiones relacionadas