Passa ai contenuti principali

Android Studio - Ripristino dell'Activity

In questo articolo vedremo come poter ripristinare l'Activity a seguito di un cambiamento di configurazione (come l'orientamento dello schermo, la disponibilità della tastiera e quando l'utente attiva la modalità multi-finestra).

Maggiori informazioni si possono trovare a questo indirizzo (in inglese)

Quando l'Activity inizia a fermarsi, il sistema chiama la funzione onSaveInstanceState() in modo che l'Activity possa salvare le informazioni sullo stato. L'implementazione predefinita di questa funzione salva informazioni transitorie sullo stato della gerarchia di visualizzazione dell'Activity, come il testo in una EditText o la posizione di una SeekBar, ecc.

Vediamo un'esempio:
Ecco come si presenta il file activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="8dp"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Inizializzazione variabile = 2"
android:textColor="#000000"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Calcola" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Risultato = "
android:textColor="#000000"
android:textSize="16sp" />
</LinearLayout>
Ecco come si presenta il file MainActivity.kt
package com.dm.tutorialactivityreload
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
//dichiarazione e inizializzazione di alcune variabili
private var numero1: Int? = 2
private var numero2: Int? = 0
private var somma: Int? = null
//Funzione onCreate() che viene eseguita quando si avvia l'Activity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//con questa riga di codice viene specificato quale layout l'Activity deve impostare
setContentView(R.layout.activity_main)
somma = numero1!! + numero2!!
textView.text = somma.toString()
button2.setOnClickListener {
somma = numero1!! + 1
textView.text = somma.toString()
}
}
}
Ed ecco il risultato:
Avvio dell'app
Pulsante Calcola premuto
Orientamento dello schermo cambiato da portrait a landscape o viceversa


Se si preme il pulsante "Calcola" viene aggiornato il calcolo nella TextView ma se ruotiamo lo schermo il calcolo viene aggiornato tramite le righe 20 e 21 inizializzando le due variabili ai valori impostati alle righe 10 e 11.
Una soluzione potrebbe essere quella vista in questo articolo impostando l'attributo:
android:configChanges="orientation|screenSize"
ma comporta alcuni svantaggi come ad esempio:
Se abbiamo definito più layout in base al dispositivo utilizzato, questo non viene caricato quando orientiamo lo schermo.

Quindi la soluzione potrebbe essere quella dell'utilizzo di onSaveInstanceState() ecco come:
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("n1", numero1!!)
outState.putInt("n2", numero2!!)
}
tramite l'attributo outState.putInt("nome etichetta", variabile) e possibile salvare la variabile di tipo Int in un "cassetto" dal nome che viene definito in "nome etichetta".
Importante sapere che per ogni tipo di variabile (Int, Double, String, ecc.) occorre modificare outState.put... ecco alcuni esempi:
//variabile di tipo Int da memorizzare
outState.putInt("nome etichetta", variabile)
//variabile di tipo Double da memorizzare
outState.putDouble("nome etichetta", variabile)
//variabile di tipo String da memorizzare
outState.putString("nome etichetta", variabile)

poi occorre richiamare le variabili memorizzate tramite la funzione onRestoreInstanceState()
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
numero1 = savedInstanceState.getInt("n1")
numero2 = savedInstanceState.getInt("n2")
}
Anche in questo caso in base al tipo di variabile che vogliamo richiamare occorre specificarne il tipo in savedInstanceState.get... dove al posto dei puntini occorre scrivere: Int, Double, String, ecc.

N.B. La funzione onRestoreInstanceState() viene richiamata subito dopo onStart() e prima di onResume() quando l'Activity viene reinizializzata da uno stato precedentemente salvato, fornito in saveInstanceState(). La maggior parte delle implementazioni utilizzerà semplicemente onCreate() per ripristinare il loro stato, ma a volte è conveniente farlo qui dopo che è stata eseguita tutta l'inizializzazione o per consentire alle sottoclassi di decidere se utilizzare l'implementazione predefinita. L'implementazione predefinita di questo metodo esegue un ripristino di qualsiasi stato di visualizzazione precedentemente salvato da onSaveInstanceState().
Questa funzione viene chiamata solo quando si ricrea un'Activity; questa funzione non viene chiamata se onStart() viene chiamato per qualsiasi altro motivo.

Quindi è molto importate sapere in quale funzione (si raccomanda onResume() per migliori prestazioni) implementare la propria app in modo da poter sfruttare onRestoreInstanceState() per questo motivo fare riferimento a questo articolo.

Vediamo un esempio pratico:
Ecco come si presenta il file MainActivity.kt
package com.dm.tutorialactivityreload
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
//dichiarazione e inizializzazione di alcune variabili
private var numero1: Int? = 2
private var numero2: Int? = 0
private var somma: Int? = null
//Funzione onCreate() che viene eseguita quando si avvia l'Activity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//con questa riga di codice viene specificato quale layout l'Activity deve impostare
setContentView(R.layout.activity_main)
}
//Funzione onResume() viene eseguita appena prima che l'Activity inizi a interagire con l'utente
//e subito dopo onRestoreInstanceState()
override fun onResume() {
super.onResume()
somma = numero1!! + numero2!!
textView.text = somma.toString()
button2.setOnClickListener {
numero2 = 1
somma = numero1!! + numero2!!
textView.text = somma.toString()
}
}
//salvataggio delle variabili
override fun onSaveInstanceState(outState: Bundle) {
outState.putInt("n1", numero1!!)
outState.putInt("n2", numero2!!)
super.onSaveInstanceState(outState)
}
//recupero delle variabili salvate
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
numero1 = savedInstanceState.getInt("n1")
numero2 = savedInstanceState.getInt("n2")
}
}
Da notare rispetto al codice precedente come le righe di codice:
somma = numero1!! + numero2!!
textView.text = somma.toString()
button2.setOnClickListener {
numero2 = 1
somma = numero1!! + numero2!!
textView.text = somma.toString()
}
sono state spostate dalla funzione onCreate() alla funzione onResume() altrimenti onRestoreInstanceState() non avrebbe effetto se fossero rimaste all'interno della funzione onCreate().

Avvio dell'app
Pulsante Calcola premuto
Orientamento dello schermo cambiato da portrait a landscape o viceversa


Download Project
Download file APK


Commenti

Post popolari in questo blog

Android Studio - Impostare lingua app

In questo articolo vedremo come poter selezionare la lingua all'interno della nostra app. Nel precedente articolo in cui si parlava del file string.xml , la lingua dell'app veniva selezionata automaticamente in base alle impostazioni del dispositivo, mentre qui vedremo come poter selezionare a proprio piacimento la lingua che dovrà avere la nostra app indipendentemente dall'impostazione del dispositivo. Per prima cosa creare il layout Ecco un esempio do come può essere il file activity_main.xml Ora creare le stringhe di testo all'interno del file string.xml Ora creare la traduzione del file string.xml nelle varie lingua come descritto in questo articolo Il risultato sarà una serie di file string.xml delle varie lingue impostate. Ora queste di seguito sono tre funzioni che servono per: selezione della lingua salvataggio della selezione nelle preferenze dell'app caricamento della lingua quando si avvia l'app Ecco come si presenta il file Main...

Android Studio - Rinominare il progetto

Rinominare il progetto Android Studio ATTENZIONE!: non eseguire questa procedura se l'app è stata pubblicata su Google Play Store Quando si vuole cambiare nome al progetto: nome cartella in cui è contenuto il progetto package name bisogna eseguire questi passaggi: Andare nella cartella dove è contenuto il progetto Creare una copia del progetto in questione Rinominare la cartella copiata con il nome dell'app (non usare spazi tra le parole) Ora è necessario dire ad Android Studio il nome del nuovo progetto  Aprire Android Studio Aprire il progetto creato in precedenza Una volta caricato il progetto cliccare Build Cliccare Clean Project Attendere che venga eseguito il processo di "pulitura" Cliccare ancora su Build Cliccare su Rebuild Project Attendere che venga ricostruito il progetto Ora aprire la cartella app fino a visualizzare la cartella java Cliccare sull'ingranaggio  Deselezionare la voce Compact Middle Packa...

Arduino - Lettura tensione potenziometro e display LCD

Leggere il valore di un poteziometro (parte 2) Oggi vedremo come leggere il valore in tensione di un potenziometro collegato al pin Analogico A0 di Arduino.