Soy muy nuevo en programación en Android y han estado experimentando con la construcción de una aplicación. En mi nueva app puedo hacer que el usuario pulse un botón que les permite elegir una aplicación en su dispositivo, tales como «Gallery» para seleccionar una imagen. Esta imagen se muestra a continuación en un imageview ventana en la pantalla de actividad. Por desgracia, cuando enciendo mi teléfono y los cambios de orientación, la imagen se pierde y se tienen que ir a seleccionar de nuevo.

¿Cómo puedo guardar la imagen de mapa de bits y tener que re-aparece después de que el cambio de orientación?

Aquí es la función de código que uso para que el usuario elija una imagen de la aplicación, elegir una imagen y mostrar la imagen en el imageview ventana.

@Override
protected void onActivityResult( int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK){
        Uri targetUri = data.getData();
        textTargetUri.setText(targetUri.toString());
        Bitmap bitmap;
        try {
            bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri));
            targetImage.setImageBitmap(bitmap);
        } 
        catch (FileNotFoundException e){
            e.printStackTrace();
        }
    }   
}

La función anterior se inicializa en mi onCreate en respuesta a un clic de botón que se muestra en este código:

Button buttonLoadImage = (Button)findViewById(R.id.loadimage);
textTargetUri = (TextView)findViewById(R.id.targeturi);
targetImage = (ImageView)findViewById(R.id.targetimage);

buttonLoadImage.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
    Intent   intent = new Intent(Intent.ACTION_PICK,
    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(intent, 0);
}});

Esencialmente, sólo tengo que poner este booleano en mi onCreate y lo han puesto de nuevo la imagen en la ventana. También muestra un texto que indica que la imagen se encuentra en el dispositivo, pero que no es tan importante para mí como ser capaz de tener la imagen en la pantalla.

if (savedInstanceState != null) {


} 

Pero parece borrar los datos después del cambio de orientación?
No tengo idea de cómo guardar los datos y restaurar a ser utilizado dentro de dicho valor booleano.
Agradezco cualquier consejo, código, o los enlaces que pueden ofrecer!


ACTUALIZACIÓN:

Gracias Vishal Vijay y rajahsekar por su rápida y útil de las respuestas. El uso tanto de su advertido de codificación así como algún código que me había encontrado a partir de la investigación anterior, que fue capaz de compilar una solución. Sin embargo, mientras se resuelve el primer problema, generado otro que voy a describir después de mostrar el código que he usado para solucionar el problema inicial.

Me enteré de que tenía 2 opciones disponibles para la restauración de la porción.

Yo podría colocar este en el onCreate:

if (savedInstanceState != null) {
        //if there is a bundle, use the saved image resource (if one is there)
        image = savedInstanceState.getParcelable("BitmapImage");
        targetImage.setImageBitmap(image);
        textTargetUri.setText(savedInstanceState.getString("path_to_picture"));R.drawable.camera_button);
    }   

Esto me permitió tener tanto la imagen así como la ruta de acceso en el dispositivo se vuelve a mostrar en mi actividad.

O podría tener esto después de que el onCreate

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState){       
        image = savedInstanceState.getParcelable("BitmapImage");
        targetImage.setImageBitmap(image);
        textTargetUri.setText(savedInstanceState.getString("path_to_picture"));
}

y la función de ahorro de las que he usado fue

@Override 
public void onSaveInstanceState(Bundle savedInstanceState){
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putParcelable("BitmapImage", bitmap);
    savedInstanceState.putString("path_to_picture", picture_location);
}   

Para aclarar donde picture_location vino, de vuelta en mi onActivityResult función que he añadido una línea y cambió otra para guardar la cadena de ruta de acceso

if (resultCode == RESULT_OK){
    Uri targetUri = data.getData();
    picture_location = targetUri.toString();
    textTargetUri.setText(picture_location);

Como para las variables inicializadas antes de que el onCreate,

Bitmap image;
Bitmap bitmap;
String picture_location;

Ahora, me doy cuenta de que esto lo ha conseguido algo muy largo pero espero que ayude a otros que pueden tener un problema similar. Como para el nuevo tema que he mencionado antes, cuando me gire mi dispositivo android, no en el hecho de mantener los datos y volver a la pantalla como yo estaba tratando de hacer. Sin embargo, cuando me gire la pantalla de nuevo, el problema original se levanta; los datos parece estar perdido y no se mostrará en la pantalla.

Tengo la esperanza de que hay una forma mucho más sencilla corrección para que el guardar y restaurar las funciones de seguir trabajando, no importa cuántas veces la orientación de la pantalla cambia?

Gracias de nuevo chicos!

el uso de Android de Consulta para que.

OriginalEl autor DeadJohnDoe | 2014-01-11

6 Comentarios

  1. 4
    Bitmap image;
    
    public void onCreat(..){
        if (savedInstanceState != null) {
            image = (Bitmap) savedInstanceState.getParcelableExtra("BitmapImage");; 
        } else { 
            image = yourBitmapImage;
        } 
    }
    
    @Override public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putExtra("BitmapImage", bitmap);
    }
    Si recuerdo correctamente, el eclipse se quejó de que putExtra y getParcelableExtra métodos están definidos por el tipo de Paquete. Yo podría haber integrado el código incorrectamente para este error a suceder. Hay una razón por la que si{} else{} en lugar de sólo la si(!=){} que he utilizado? Con el if else solucionar mi problema de que sólo trabajando por un cambio de orientación?

    OriginalEl autor Vishal Vijay

  2. 3

    Creo que cuesta demasiado si guarda un Bitmap en onSaveInstanceState,como onSaveInstanceState será llamado antes de onStop cada vez,y Bitmap es una gran cosa.

    Creo que es mejor ahorrar un URI en onSaveInstanceState

    Uri mUri;
    ImageView mImageView;
    
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      ...
      if (savedInstanceState != null){
        mUri = savedInstanceState.getParcelable("uri");
        mImageView.setImageURI(mUri);
      }
    }
    
    
    protected void onActivityResult( int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK){
            Uri targetUri = data.getData();
            ...
            mUri = targetUri;
        }   
    }
    public void onSaveInstanceState(Bundle outState) {
            if (mURI !=null) {
                outState.putParcelable("uri", mUri);
            }
        }

    OriginalEl autor footman

  3. 1

    de acuerdo a la guía del desarrollador de https://developer.android.com/topic/performance/graphics/cache-bitmap.html.

    la forma recomendada es utilizar setRetainInstance(true) en el fragmento de retener imágenes.

    referencia a la sección de «Manejar los Cambios de Configuración»

    Tiempo de ejecución de los cambios de configuración, tales como la orientación de la pantalla cambie, causa de Android para destruir y reiniciar el funcionamiento de la actividad, con la nueva configuración (Para obtener más información acerca de este comportamiento, consulte gestión de Cambios de ejecución). Quieres evitar tener que procesar todas las imágenes de nuevo de modo que el usuario tiene un suave y rápido, la experiencia cuando un cambio en la configuración se produce.

    Por suerte, usted tiene una buena memoria caché de mapas de bits que se genera en el Uso de una Memoria Caché de la sección. Esta caché puede ser pasado a través de la nueva instancia de la actividad utilizando un Fragmento que se conserva llamando setRetainInstance(true)). Después de la actividad ha sido recreado, este conserva el Fragmento se vuelve a unir y ganar acceso a la caché de objetos, permitiendo que las imágenes se recuperan rápidamente y volver a rellenar en el ImageView objetos.

    private LruCache<String, Bitmap> mMemoryCache;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        RetainFragment retainFragment =
                RetainFragment.findOrCreateRetainFragment(getFragmentManager());
        mMemoryCache = retainFragment.mRetainedCache;
        if (mMemoryCache == null) {
            mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
                ... //Initialize cache here as usual
            }
            retainFragment.mRetainedCache = mMemoryCache;
        }
        ...
    }
    
    class RetainFragment extends Fragment {
        private static final String TAG = "RetainFragment";
        public LruCache<String, Bitmap> mRetainedCache;
    
        public RetainFragment() {}
    
        public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) {
            RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG);
            if (fragment == null) {
                fragment = new RetainFragment();
                fm.beginTransaction().add(fragment, TAG).commit();
            }
            return fragment;
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setRetainInstance(true);
        }
    }

    OriginalEl autor Angel Koh

  4. 0

    Uso onSaveInstanceState para guardar la imagen

    if (savedInstanceState == null) {
        image = R.drawable.default;
    } else {
         //if there is a bundle, use the saved image resource (if one is there)
         image = savedInstanceState.getInt(IMAGE_RESOURCE, R.drawable.default);
    }
    
    @Override
    public void onSaveInstanceState(Bundle outState) {
        //Make sure you save the current image resource 
        outState.putInt(IMAGE_RESOURCE, image);
        super.onSaveInstanceState(outState);
    }
    
    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        outState.getInt(IMAGE_RESOURCE,image);
        super.onRestoreInstanceState(state);
    }
    Hay una razón por la que si{} else{} en lugar de sólo la si(!=){} que he utilizado? Con el if else solucionar mi problema de que sólo trabajando por un cambio de orientación?

    OriginalEl autor rajahsekar

  5. -1

    Agregar android:configChanges="keyboardHidden|orientation" para su Actividad en el archivo de Manifiesto.

    Mal enfoque. Usted debe controlar la orientación del cambio de forma manual.
    Había encontrado su respuesta como una «solución» previamente, por desgracia, no funciona. Al menos, no con mi programa.

    OriginalEl autor Manali Sheth

Dejar respuesta

Please enter your comment!
Please enter your name here