2012-03-06 16 views
9

Antes que nada, soy nuevo en Desarrollo de Android, así que tenga paciencia conmigo.Actividad que se está creando dos veces en Android

Comenzaré desde la interfaz de usuario, tengo un botón que una vez que lo toca, comienza una actividad para obtener un resultado.

public class GUIActivity extends Activity 

    @Override 
    public void onClick(....){ 
     Intent intent = new Intent(getApplicationContext(), GetImageActivity.class); 
     intent.putExtra("action", FROM_CAMERA); 
     startActivityForResult(intent, GET_IMAGE); 
    } 

    @Override 
    onActivityResult(int requestCode, int resultCode, Intent data){ 
     Log(TAG, "onActivityResult"); 
     //handle result 
    } 

} 

La clase GetImageActivity es un contenedor para otras dos actividades, una para capturar una imagen de la cámara y otra conseguirlo desde la galería. Devuelve y Uri objeto de la imagen seleccionada.

public class GetImageActivity extends Activity{ 
    private Uri mediaUri; 

    @Override 
    public void onCreate(Bundle savedInstanceState){ 
     super.onCreate(savedInstanceState); 
     Bundle extras = getIntent().getExtras(); 
     int action = extras.getInt("action"); 

     Log.d(TAG, "onCreate"); 

     switch(action){ 
      case FROM_CAMERA: 
       mediaUri = Uri.fromFile(new File(....)); 
       Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); 
       intent.putExtra(MediaStore.EXTRA_OUTPUT, mediaUri); 

       Log.d(TAG, "Calling camera activity" 
       startActivityForResult(intent, action); 
       break; 
      case FROM GALLERY: 
       //... 
     }    
    } 

    @Override 
    onActivityResult(int requestCode, int resultCode, Intent data){ 
     Log.d(TAG, "onActivityResult"); 

     switch(requestCode){ 
      case FROM_CAMERA: 
       if(resultCode == Activity.RESULT_OK){ 
        Intent data = new Intent(); 
        data.putExtra("uri", mediaUri); 
        setResult(Activity.RESULT_OK, data); 
        finish(); 
       }else{ 
        Log.e(TAG, "Camera activity failed!"); 
        setResult(Activity.RESULT_CANCELED); 
        finish(); 
       } 
       break; 

      case FROM_GALLERY: 
       //... 

     } 
    } 
} 

Esto es lo que se espera que suceda cuando el usuario hace clic en el botón:

  • La actividad de la cámara debe comenzar.
  • Una vez que el usuario toma una foto, debe devolver su URI a la clase de la GUI.

veces (por lo general es una probabilidad del 50%) que trabaja en espera, pero otras veces esto es lo que sucede: se inicia

  • actividad de la cámara.
  • El usuario toma una foto.
  • La actividad de la cámara comienza de NUEVO.
  • El usuario puede tomar otra foto o retroceder.
  • En cualquier caso, el URI que vuelve a la clase de la GUI no existe.

He agregado un par de líneas de registro de depuración para seguir la secuencia de eventos. Cuando llegue el mal comportamiento esta es la salida me sale:

  • GetImageActivity - onCreate
  • GetImageActivity - Llamando Actividad cámara

La cámara se abre, y una vez que he tomado una imagen que dice :

  • GetImageActivity - onCreate (de nuevo)
  • GetImageActivity - Llamar a la cámara Actividad
  • GetImageActivity - onActivityResult

Se abre la cámara por segunda vez. El usuario toma otra imagen y:

  • GetImageActivity - onActivityResult
  • GUIActivity - onActivityResult

Así que mi pregunta es ... lo que podría provocar que el GetImageActivity ser llamado dos veces?

Respuesta

6

El problema es el manejo inadecuado del ciclo de vida Activity.

La segunda llamada al onCreate es para manejar el resultado.

Android puede elegir destruir un Activity que está esperando la llamada al onActivityResult; especialmente cuando la memoria libre se está agotando. Algunos dispositivos parecen más agresivos para destruir las actividades que están en la pila de tareas. Puedo recrear de manera confiable el problema en un dispositivo Samsung configurado en un modo de depuración llamado "modo estricto".

Puede verificar si este es su problema al registrar llamadas a onCreate & onDestroy.

En el caso de una actividad destruida, cuando el resultado de la actividad deba procesarse, Android recreará el Activity, pasando un al onCreate. Entonces, el remedio es verificar el valor de savedInstanceState en su GetImageActivity.onCreate. Si no es null, no realice ninguna llamada al startActivity porque su Activity se está recreando para llamar al onActivityResult.

Opcionalmente, si necesita preservar cualquier estado, anule onSaveInstanceState(Bundle outState) y ponga los datos que necesita en outState.

0

Cuando llama al startActivityForResult, le dice a Android que desea que el resultado se entregue en el Activity que realiza esa llamada.Lo que explica lo que ves cuando registraste GetImageActivity - onCreate (again).

Ya que invocan startActivityForResult en su primera actividad, es decir, GUIActivity que debiera estar llamando setResult en GetImageActivity para pasar adecuadamente vuelta el resultado.

Así que en GetImageActivity.onActivityResult() justo antes de llamar finish() debe llamar setResult de manera que cuando regrese de nuevo a GUIActivity Puede manejar el resultado esperado.

+0

Voy a editar el código para hacer más claro . Donde dice '// manejar el resultado' en la clase' GetImageActivity', realmente llamo 'setResult()'. Lo que hay que notar es que la actividad se crea nuevamente incluso antes de que se llame a su método 'onActivityResult()' por primera vez. –

1

Añadir esta definición a su actividad en AndroidManifest.xml:

android:launchMode = "singleInstance" 
1

Agregar a su definición Actividad en AndroidManifest.xml:

android:launchMode = "singleTask" 
Cuestiones relacionadas