Autore Topic: Problema con l' onSaveInstanceState  (Letto 772 volte)

Offline Smith

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus 4
  • Sistema operativo:
    Ubuntu 13.04
Problema con l' onSaveInstanceState
« il: 04 Maggio 2013, 12:22:08 CEST »
0
Ho cancellato il post precedente perchè da una serie di ricerche sembro arrivato ad una soluzione.
Ancora, però, non funzionante.

Riepilogo il problema:
Ho una MainActivity con un button ed una imageButton
Se clicco sul button richiamo la galleria e carico una immagine nella imageButton.
Se clicco sull'imageButton richiamo l'activity MyOptions formata da button che richiamano a loro volta altre activity.
Se clicco sul button InsertText richiamo l'activity MyOption1 che fa inserire un testo all'utente e quando quest'ultimo clicca su OK ritorna alla mainActivity visualizzando il testo in un Dialog.
Solo che nella MainActivity l'immagine precedentemente caricata non c'è.

Penso dunque di usare l'onSaveInstanceState per rendere persistente l'immagine nella imageButton e lo faccio in questa maniera:

Codice (Java): [Seleziona]
package com.example.android_1_7;

import java.io.InputStream;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends Activity {
        private static final int REQUEST_CODE = 1;
        private Bitmap bitmap;
        private ImageView imageView;
       
        @Override
        protected void onSaveInstanceState(Bundle savedInstanceState)
        {
                super.onSaveInstanceState(savedInstanceState);
                //imageView = (ImageView) findViewById(R.id.imageButton1);
                if(imageView.getContentDescription() != null)
                {
                        CharSequence characters = imageView.getContentDescription();
                        savedInstanceState.putString("image", characters.toString());                  
                }
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                imageView = (ImageView) findViewById(R.id.imageButton1);
               
                if(savedInstanceState != null)
                {
                        imageView.setContentDescription(savedInstanceState.getString("image"));
                       
                        Bundle bundle = getIntent().getExtras();
                        if(bundle != null)
                        {
                                String pkg = getPackageName();
                                String text = bundle.getString(pkg + "Stringa");
                                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                                builder.setMessage(text);
                                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                       
                                        @Override
                                        public void onClick(DialogInterface arg0, int arg1) {
                                                // TODO Auto-generated method stub
                                                arg0.dismiss();                                
                                        }
                                });
                                AlertDialog dialog = builder.create();
                                dialog.show();
                        }                      
                }
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getMenuInflater().inflate(R.menu.main, menu);
                return true;
        }
       
        public void selectImage(View view)
        {
                Intent image = new Intent();
                image.addCategory(Intent.CATEGORY_OPENABLE);
                image.setAction(Intent.ACTION_GET_CONTENT);
                image.setType("image/*");
                startActivityForResult(image, REQUEST_CODE);
        }
       
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data)
        {
                if(requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK)
                {
                        try
                        {
                                if(bitmap != null)
                                {
                                        bitmap.recycle();
                                }
                                InputStream stream = getContentResolver().openInputStream(data.getData());
                                bitmap = BitmapFactory.decodeStream(stream);
                                imageView.setImageBitmap(bitmap);
                        }
                        catch (Exception e)
                        {
                                e.printStackTrace();
                        }
                }
        }
       
        public void selectOptions(View view)
        {
                Intent options = new Intent(this, MyOptions.class);
                startActivity(options);
        }
}

Ma non funge.
Cosa sbaglio???
« Ultima modifica: 05 Maggio 2013, 10:40:08 CEST da Smith »

Offline NanoAndroide

  • Utente junior
  • **
  • Post: 63
  • Respect: +3
    • Google+
    • Mostra profilo
    • MeToo
  • Dispositivo Android:
    GT-S5570
  • Play Store ID:
    MeToo
  • Sistema operativo:
    Windows 7
Re:Problema con l' onSaveInstanceState
« Risposta #1 il: 05 Maggio 2013, 12:23:33 CEST »
0
Non mi pare molto chiaro...
Dici di avere un button ed un imagebutton, ma nel codice vedo solo una imageview ed il button del dialog.
Su pressione del button del dialog non fa altro che che chiudere lo stesso, quindi ciccia.
L'imageview, mi pare venga modificata solo in onActivityResult, ma di quale activity?
All'unico riferimento a startActivityForResult che vedo non viene passata alcuna activity...
Sinceramente, mi preoccuperei se funzionasse...

Non ti conviene salvare l'id dell'immagine che vuoi usare in sharedpreferences e poi applicarla ricaricando l'activity?

Offline Smith

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus 4
  • Sistema operativo:
    Ubuntu 13.04
Re:Problema con l' onSaveInstanceState
« Risposta #2 il: 05 Maggio 2013, 12:39:06 CEST »
0
Vedi solo la imageButton perchè al button ho associato la funzione selectImage che viene richiamata solo al tap del button.

onActivityResult viene richiamata da startActivityForResult nella selectImage

E il caricamento dell'immagine nella imageButton avviene con successo.

Citazione
Non ti conviene salvare l'id dell'immagine che vuoi usare in sharedpreferences e poi applicarla ricaricando l'activity?
Proverò ad indagare...

Se ci sono altri suggerimenti................

Puoi vedere con i tuoi occhi il corretto funzionamento del caricamento di un'immagine presa dalla gallery in quuesto video:

https://www.youtube.com/watch?v=7z8UeiqlGv8
« Ultima modifica: 05 Maggio 2013, 13:00:20 CEST da Smith, Reason: Video di conferma »

Offline NanoAndroide

  • Utente junior
  • **
  • Post: 63
  • Respect: +3
    • Google+
    • Mostra profilo
    • MeToo
  • Dispositivo Android:
    GT-S5570
  • Play Store ID:
    MeToo
  • Sistema operativo:
    Windows 7
Re:Problema con l' onSaveInstanceState
« Risposta #3 il: 05 Maggio 2013, 12:58:09 CEST »
0
Vedi solo la imageButton perchè al button ho associato la funzione selectImage che viene richiamata solo al tap del button.
Nell'xml, con android:onClick? Ok, non c'avevo pensato...  :-P

Proverò ad indagare...
Te la caveresti davvero con poca fatica, credimi...  :D


Offline Smith

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus 4
  • Sistema operativo:
    Ubuntu 13.04
Re:Problema con l' onSaveInstanceState
« Risposta #4 il: 05 Maggio 2013, 13:14:43 CEST »
0
...ricaricando l'activity...

Non mi piace...
Ho letto qualcosina velocemente...
Praticamente dovrei far fare un'operazione all'activity che già ha fatto in precedenza...
Io invece volevo in qualche modo salvarmi lo stato dell'activity e, quando veniva richiamata, volevo ricaricare lo stato...
Il problema è che non ho ancora capito il lifecycle di questa activity...
Voglio dire...quando clicco sull'imageButton per passare dalla MainActivity alla MyOptions activity, la MainActivity viene killata, stoppata messa in pausa?
E se viene killata, perchè? Non dovrebbe andare solo in background?
Ho un po' di confusione a riguardo ma non riesco a capire cosa succede alla mia MainActivity...
Se qualcuno riuscisse a darmi delucidazioni a riguardo risolverei il problema :D

[Edit]
Allora...da un po' di prove effettuate sul codice ho capito che viene richiamata la onPause() una volta che tappo sull'imageButton.
La onSaveInstanceState, invece, viene richiamata una sola volta prima di entrare nella Gallery per scegliere l'immagine.
Dunque si salva lo stato prima del caricamento dell'immagine nell'imageButton...dovrebbe essere questo il problema.
Quando clicco sull'imageButtonl la onSaveInstanceState non viene richiamata...
Qualcuno saprebbe spiegarmi il perchè?

[Edit2]
La onSaveInstanceState viene richiamata ogni volta che la MainActivity va in backgroud...Dunque funziona come dovrebbe...
A questo punto sia una questione di salvare la giusta variabile per poi farne il restore quando viene richiamata la Mainactivity.
Girando un po' in rete ho visto che qualcuno salva l'Uri dell'immagine per poi richiamarla al restore...
Qualcuno si è già imbattuto in questa cosa?

[Edit3]
Leggendo un po' in rete sono arrivato a buttare giu queste righe di codice, forse logicamente più corrette rispetto al listato di prima.
Ma non funziona...

la savedInstanceState è sempre uguale a null  o_O

Codice (Java): [Seleziona]
package com.example.android_1_7;

import java.io.InputStream;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends Activity {
        private static final int REQUEST_CODE = 1;
        private Bitmap bitmap;
        private ImageView imageView;
        private static final String KEY_CONTENT = "image";
        private Uri imagePath;
        private static final String TAG = "tag";

       
        @Override
        public void onSaveInstanceState(Bundle savedInstanceState)
        {
                if(imagePath != null)
                {
                        savedInstanceState.putString(KEY_CONTENT, imagePath.toString());
                        Log.v(TAG, savedInstanceState.getString(KEY_CONTENT));
                }
                super.onSaveInstanceState(savedInstanceState);
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                setContentView(R.layout.activity_main);
                imageView = (ImageView) findViewById(R.id.imageButton1);
                if(savedInstanceState != null && !savedInstanceState.isEmpty())
                {
                        Log.v(TAG, savedInstanceState.getString(KEY_CONTENT));
                        //imageView = (ImageView) findViewById(R.id.imageButton1);
                        try
                        {
                                InputStream stream = getContentResolver().openInputStream(Uri.parse(savedInstanceState.getString(KEY_CONTENT)));
                                bitmap = BitmapFactory.decodeStream(stream);
                                imageView.setImageBitmap(bitmap);                      
                        }
                        catch (Exception e)
                        {
                                e.printStackTrace();
                        }
                       
                        Bundle bundle = getIntent().getExtras();
                        if(bundle != null)
                        {
                                String pkg = getPackageName();
                                String text = bundle.getString(pkg + "Stringa");
                                dialogMainActivity(text);                              
                        }                      
                }
                super.onCreate(savedInstanceState);
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getMenuInflater().inflate(R.menu.main, menu);
                return true;
        }
       
        public void selectImage(View view)
        {
                Intent image = new Intent();
                image.addCategory(Intent.CATEGORY_OPENABLE);
                image.setAction(Intent.ACTION_GET_CONTENT);
                image.setType("image/*");
                startActivityForResult(image, REQUEST_CODE);
        }
       
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data)
        {
                super.onActivityResult(requestCode, resultCode, data);
                if(requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK)
                {
                        try
                        {
                                if(bitmap != null)
                                {
                                        bitmap.recycle();
                                }
                                InputStream stream = getContentResolver().openInputStream(data.getData());
                                bitmap = BitmapFactory.decodeStream(stream);
                                imageView.setImageBitmap(bitmap);
                                imagePath = data.getData();
                        }
                        catch (Exception e)
                        {
                                e.printStackTrace();
                        }
                }
        }
       
        public void selectOptions(View view)
        {
                Intent options = new Intent(this, MyOptions.class);
                startActivity(options);
        }
       
        public void dialogMainActivity(String text)
        {
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setMessage(text);
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                       
                        @Override
                        public void onClick(DialogInterface arg0, int arg1) {
                                // TODO Auto-generated method stub
                                arg0.dismiss();                                
                        }
                });
                AlertDialog dialog = builder.create();
                dialog.show();
        }
}

[Edit4]
Te la caveresti davvero con poca fatica, credimi...  :D

Avevi ragione. Ho risolto tutto con le sharedpreferences.
Da quanto ho capito l'onResultInstanceState fa il restore di uno stato salvato nell'onStateInstanceState nel caso in cui l'activity viene distrutta.
Dato che la mia activity va in pausa e quando la richiamo con un intent la "starto" di nuovo con startActivity, l'onRestoreInstanceState non veniva mai richiamata.

Ora, però, mi chiedo una cosa.
Avvio l'activity A
Richiamo la B
La A va in background e la B passa in foreground
Dalla B "starto" nuovamente la A.

Questo "starto nuovamente la A" significa che ho 2 Activity A (una in background e la nuova in foreground) oppure viene semplicemente re-inizializzata e messa in foreground l'unica activity A ancora in esecuzione???

Metto risolto, ma vorrei che qualcuno mi schiarisse un po' le idee :D
« Ultima modifica: 06 Maggio 2013, 12:22:31 CEST da Smith »

Offline NanoAndroide

  • Utente junior
  • **
  • Post: 63
  • Respect: +3
    • Google+
    • Mostra profilo
    • MeToo
  • Dispositivo Android:
    GT-S5570
  • Play Store ID:
    MeToo
  • Sistema operativo:
    Windows 7
Re:Problema con l' onSaveInstanceState
« Risposta #5 il: 07 Maggio 2013, 11:59:27 CEST »
+1
[Edit4]
Avevi ragione. Ho risolto tutto con le sharedpreferences.
Da quanto ho capito l'onResultInstanceState fa il restore di uno stato salvato nell'onStateInstanceState nel caso in cui l'activity viene distrutta.
Dato che la mia activity va in pausa e quando la richiamo con un intent la "starto" di nuovo con startActivity, l'onRestoreInstanceState non veniva mai richiamata.

Ora, però, mi chiedo una cosa.
Avvio l'activity A
Richiamo la B
La A va in background e la B passa in foreground
Dalla B "starto" nuovamente la A.

Questo "starto nuovamente la A" significa che ho 2 Activity A (una in background e la nuova in foreground) oppure viene semplicemente re-inizializzata e messa in foreground l'unica activity A ancora in esecuzione???

Metto risolto, ma vorrei che qualcuno mi schiarisse un po' le idee :D

Scusa l'assenza di risposte, sono stato via qualche giorno...  :-P

Dunque, prima di tutto ti conviene dare un'occhiata allo schema nella pagina linkata qui sotto, dove dice 'Activity Lifecycle':
Activity | Android Developers

In effetti, le Activity, non vengono praticamente mai distrutte, a meno che non venga terminata con finish() o ci siano problemi di memoria quando questa non è in esecuzione. Di solito passano in onPause() e se non vengono richiamate a lungo vengono messe in onStop(). Quando sono in onStop hanno priorità più bassa, quindi se scarseggia la memoria sono candidate ad essere rimosse. Nel tuo esempio, se da A avvii B, senza però invocare finish(), A va in onPause. Lo stesso succede nel passaggio da B ad A.