1. Benvinguts
Aquest laboratori pràctic forma part de la Unitat 1: Iniciació al curs Fonaments per a desenvolupadors d'Android (versió 2). Treureu el màxim profit d'aquest curs si treballeu els laboratoris de codificació en seqüència:
- Per obtenir la llista completa de codelabs del curs, vegeu Codelabs for Android Developer Fundamentals (V2).
- Per obtenir més informació sobre el curs, inclosos els enllaços a tots els capítols conceptuals, aplicacions i diapositives, consulteu Fonaments per a desenvolupadors d'Android (versió 2).
Introducció
En aquesta pràctica aprendràs més sobre el cicle de vida de l'activitat. El cicle de vida és el conjunt d'estats en què pot estar una activitat durant tota la seva vida útil, des del moment en què es crea fins al moment en què es destrueix i el sistema recupera els seus recursos. A mesura que un usuari navega entre les activitats de la vostra aplicació (així com dins i fora de la vostra aplicació), les activitats passen entre diferents estats en els seus cicles de vida.
Cada etapa del cicle de vida d'una activitat té un mètode de devolució de trucada corresponent: onCreate(), onStart(), onPause(), etc. Quan una activitat canvia d'estat, s'invoca el mètode de devolució de trucada associat. Ja heu vist un d'aquests mètodes: onCreate(). En anul·lar qualsevol dels mètodes de devolució de trucada del cicle de vida a les classes d'activitat, podeu canviar el comportament predeterminat de l'activitat en resposta a les accions de l'usuari o del sistema.
L'estat de l'activitat també pot canviar en resposta als canvis de configuració del dispositiu, per exemple, quan l'usuari gira el dispositiu de vertical a horitzontal. Quan es produeixen aquests canvis de configuració, l'activitat es destrueix i es recrea en el seu estat predeterminat i l'usuari pot perdre la informació que ha introduït a l'activitat. Per evitar confondre els usuaris, és important que desenvolupeu la vostra aplicació per evitar pèrdues de dades inesperades. Més endavant, en aquesta pràctica, experimenteu amb els canvis de configuració i apreneu a preservar l'estat d'una activitat en resposta als canvis de configuració del dispositiu i altres esdeveniments del cicle de vida de l'activitat.
En aquesta pràctica, afegiu declaracions de registre a l'aplicació TwoActivities i observeu els canvis del cicle de vida de l'activitat mentre feu servir l'aplicació. A continuació, comenceu a treballar amb aquests canvis i a explorar com gestionar l'entrada de l'usuari en aquestes condicions.
Requisits previs
Hauries de ser capaç de:
- Creeu i executeu un projecte d'aplicació a Android Studio .
- Afegiu declaracions de registre a la vostra aplicació i visualitzeu aquests registres al panell de Logcat.
- Comprendre i treballar amb una activitat i una intenció, i sentir-se còmode interactuant amb ells.
El que aprendràs
- Com funciona el cicle de vida de l'activitat.
- Quan una activitat comença, s'atura, s'atura i es destrueix.
- Sobre els mètodes de devolució de trucada del cicle de vida associats als canvis d'activitat.
- L'efecte de les accions (com ara els canvis de configuració) que poden provocar esdeveniments del cicle de vida de l'activitat.
- Com conservar l'estat de l'activitat durant els esdeveniments del cicle de vida.
Què faràs
- Afegiu codi a l'aplicació TwoActivities de la pràctica anterior per implementar les diferents trucades del cicle de vida de l'activitat per incloure declaracions de registre.
- Observeu els canvis d'estat a mesura que s'executa l'aplicació i mentre interactueu amb cada activitat de la vostra aplicació.
- Modifiqueu la vostra aplicació per mantenir l'estat d'instància d'una activitat que es recrea de manera inesperada en resposta al comportament de l'usuari o al canvi de configuració al dispositiu.
2. Visió general de l'aplicació
En aquesta pràctica s'afegeix a l'aplicació TwoActivities . L'aplicació té un aspecte i un comportament aproximadament igual que a l'últim laboratori de codificació. Conté dues implementacions d'Activity i ofereix a l'usuari la possibilitat d'enviar entre elles. Els canvis que feu a l'aplicació en aquesta pràctica no afectaran el seu comportament visible dels usuaris.
3. 3. Tasca 1: Afegiu devolucions de trucada del cicle de vida a TwoActivities
En aquesta tasca implementareu tots els mètodes de devolució del cicle de vida de l'activitat per imprimir missatges al logcat quan s'invoquin aquests mètodes. Aquests missatges de registre us permetran veure quan el cicle de vida de l'activitat canvia d'estat i com aquests canvis d'estat del cicle de vida afecten la vostra aplicació mentre s'executa.
1.1 (Opcional) Copia el projecte TwoActivities
Per a les tasques d'aquesta pràctica, modificareu el projecte de TwoActivities existent que heu creat a l'última pràctica. Si preferiu mantenir intacte el projecte anterior de TwoActivities, seguiu els passos de l'Apèndix: Utilitats per fer una còpia del projecte.
1.2 Implementar devolucions de trucada a MainActivity
- Obriu el projecte TwoActivities a Android Studio i obriu MainActivity al panell Projecte > Android.
- Al mètode onCreate(), afegiu les instruccions de registre següents:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
- Afegiu una substitució per a la devolució de trucada onStart(), amb una declaració al registre d'aquest esdeveniment:
@Override
public void onStart(){
super.onStart();
Log.d(LOG_TAG, "onStart");
}
Per obtenir una drecera, seleccioneu Codi > Anul·lació de mètodes a Android Studio. Apareix un diàleg amb tots els mètodes possibles que podeu substituir a la vostra classe. Si escolliu un o més mètodes de devolució de trucada de la llista, s'insereix una plantilla completa per a aquests mètodes, inclosa la trucada necessària a la superclasse.
- Utilitzeu el mètode onStart() com a plantilla per implementar les devolucions de trucada del cicle de vida onPause(), onRestart(), onResume(), onStop() i onDestroy().
Tots els mètodes de devolució de trucada tenen les mateixes signatures (excepte el nom). Si copieu i enganxeu onStart() per crear aquests altres mètodes de devolució de trucada, no us oblideu d'actualitzar el contingut per trucar al mètode correcte a la superclasse i registrar el mètode correcte.
- Executeu la vostra aplicació.
- Feu clic a la pestanya Logcat a la part inferior d'Android Studio per mostrar el panell Logcat. Hauríeu de veure tres missatges de registre que mostren els tres estats del cicle de vida pels quals ha transigut l'activitat quan va començar:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume
1.3 Implementar devolucions de trucada del cicle de vida a SecondActivity
Ara que heu implementat els mètodes de devolució del cicle de vida per a MainActivity, feu el mateix per a SecondActivity.
- Obriu SecondActivity.
- A la part superior de la classe, afegiu una constant per a la variable LOG_TAG:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
- Afegiu les devolucions de trucada del cicle de vida i les declaracions de registre a la segona activitat. (Podeu copiar i enganxar els mètodes de devolució de trucada des de MainActivity.)
- Afegiu una instrucció de registre al mètode returnReply() just abans del mètode finish():
Log.d(LOG_TAG, "End SecondActivity");
1.4 Observeu el registre mentre s'executa l'aplicació**
- Executeu la vostra aplicació.
- Feu clic a la pestanya Logcat a la part inferior d'Android Studio per mostrar el panell Logcat.
- Introduïu Activitat al quadre de cerca. El logcat d'Android pot ser molt llarg i desordenat. Com que la variable LOG_TAG de cada classe conté les paraules MainActivity o SecondActivity, aquesta paraula clau us permet filtrar el registre només per les coses que us interessen.
Experimenteu amb la vostra aplicació i tingueu en compte que els esdeveniments del cicle de vida que es produeixen en resposta a diferents accions. En particular, proveu aquestes coses:
- Utilitza l'aplicació amb normalitat (envia un missatge, respon amb un altre missatge).
- Feu servir el botó Enrere per tornar de la segona activitat a l'activitat principal.
- Utilitzeu la fletxa amunt de la barra de l'aplicació per tornar de la segona activitat a l'activitat principal.
- Gireu el dispositiu tant a l'activitat principal com a la segona en diferents moments de la vostra aplicació i observeu què passa al *registre i a la pantalla.
- Premeu el botó de visió general (el botó quadrat a la dreta d'Inici) i tanqueu l'aplicació (toqueu la X).
- Torna a la pantalla d'inici i reinicia l'aplicació.
CONSELL: si esteu executant la vostra aplicació en un emulador, podeu simular la rotació amb Control+F11 o Control+Funció+F11.
Codi de solució de la tasca 1
Els fragments de codi següents mostren el codi de solució per a la primera tasca.
Activitat principal
Els fragments de codi següents mostren el codi afegit a MainActivity, però no tota la classe.
El mètode onCreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Log the start of the onCreate() method.
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
}
Altres mètodes de cicle de vida:
@Override
protected void onStart() {
super.onStart();
Log.d(LOG_TAG, "onStart");
}
@Override
protected void onPause() {
super.onPause();
Log.d(LOG_TAG, "onPause");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(LOG_TAG, "onRestart");
}
@Override
protected void onResume() {
super.onResume();
Log.d(LOG_TAG, "onResume");
}
@Override
protected void onStop() {
super.onStop();
Log.d(LOG_TAG, "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(LOG_TAG, "onDestroy");
}
Segona activitat
Els fragments de codi següents mostren el codi afegit a SecondActivity, però no tota la classe.
A la part superior de la classe SecondActivity:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
El mètode returnReply():
public void returnReply(View view) {
String reply = mReply.getText().toString();
Intent replyIntent = new Intent();
replyIntent.putExtra(EXTRA_REPLY, reply);
setResult(RESULT_OK, replyIntent);
Log.d(LOG_TAG, "End SecondActivity");
finish();
}
Altres mètodes de cicle de vida:
El mateix que per a MainActivity, a dalt.
4. 4. Tasca 2: desar i restaurar l'estat de la instància d'activitat
Depenent dels recursos del sistema i del comportament dels usuaris, cada activitat de la vostra aplicació es pot destruir i reconstruir amb molta més freqüència del que podríeu pensar.
És possible que hàgiu notat aquest comportament a l'última secció quan vau girar el dispositiu o l'emulador. Girar el dispositiu és un exemple de canvi de configuració del dispositiu. Tot i que la rotació és la més habitual, tots els canvis de configuració fan que l'activitat actual es destrueixi i es torni a crear com si fos nova. Si no tens en compte aquest comportament al teu codi, quan es produeix un canvi de configuració, el disseny de l'activitat pot tornar a l'aspecte predeterminat i als valors inicials, i els usuaris poden perdre el seu lloc, les seves dades o l'estat del seu progrés a la teva aplicació.
L'estat de cada activitat s'emmagatzema com un conjunt de parells clau/valor en un objecte Bundle anomenat estat de la instància de l'activitat. El sistema desa la informació d'estat predeterminada al paquet d'estat de la instància just abans que s'atura l'activitat i passa aquest paquet a la nova instància d'activitat per restaurar-lo.
Per evitar que es perdin dades en una activitat quan es destrueix i es recrea de manera inesperada, cal que implementeu el mètode onSaveInstanceState(). El sistema crida aquest mètode a la vostra activitat (entre onPause() i onStop()) quan hi ha la possibilitat que l'activitat es destrueixi i es torni a crear.
Les dades que deseu a l'estat de la instància són específiques només d'aquesta instància d'aquesta Activitat específica durant la sessió de l'aplicació actual. Quan atureu i reinicieu una sessió d'aplicació nova, l'estat de la instància d'activitat es perd i l'activitat torna al seu aspecte predeterminat. Si necessiteu desar dades d'usuari entre sessions d'aplicacions, utilitzeu preferències compartides o una base de dades. Aprèn sobre tots dos en una pràctica posterior.
2.1 Deseu l'estat de la instància d'activitat amb onSaveInstanceState()
És possible que hàgiu notat que girar el dispositiu no afecta en absolut l'estat de la segona activitat. Això es deu al fet que el segon disseny i estat de l'activitat es generen a partir del disseny i la intenció que l'ha activat. Fins i tot si es recrea l'activitat, la intenció encara hi és i les dades d'aquesta intenció encara es fan servir cada vegada que es crida al mètode onCreate() de la segona activitat.
A més, és possible que observeu que a cada activitat, qualsevol text que heu escrit als elements EditText del missatge o de la resposta es conserva fins i tot quan es gira el dispositiu. Això es deu al fet que la informació d'estat d'alguns dels elements de Visualització del vostre disseny es desa automàticament a través dels canvis de configuració, i el valor actual d'un EditText és un d'aquests casos.
Per tant, l'únic estat d'activitat que us interessa són els elements TextView per a la capçalera de resposta i el text de resposta a l'activitat principal. Tots dos elements de TextView són invisibles per defecte; només apareixen quan envieu un missatge a l'activitat principal des de la segona activitat.
En aquesta tasca, afegiu codi per preservar l'estat d'instància d'aquests dos elements TextView mitjançant onSaveInstanceState().
- Obriu MainActivity.
- Afegiu aquesta implementació d'esquelet d'onSaveInstanceState() a l'activitat o utilitzeu Codi > Mètodes de substitució per inserir una substitució d'esquelet.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
- Comproveu si la capçalera és visible actualment i, si és així, poseu aquest estat de visibilitat a l'estat Bundle amb el mètode putBoolean() i la clau "reply_visible".
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
}
Recordeu que la capçalera i el text de la resposta es marquen com a invisibles fins que hi hagi una resposta de la segona activitat. Si la capçalera és visible, hi ha dades de resposta que s'han de desar. Tingueu en compte que només ens interessa aquest estat de visibilitat: no cal desar el text real de la capçalera, perquè aquest text no canvia mai.
- Dins d'aquesta mateixa comprovació, afegiu el text de resposta al paquet.
outState.putString("reply_text",mReplyTextView.getText().toString());
Si la capçalera és visible, podeu suposar que el missatge de resposta també és visible. No cal que proveu ni deseu l'estat de visibilitat actual del missatge de resposta. Només el text real del missatge entra al paquet d'estat amb la clau "reply_text".
Deseu l'estat només d'aquells elements de visualització que poden canviar després de crear l'activitat. Els altres elements de visualització de la vostra aplicació (el text Edit, el botó) es poden tornar a crear des del disseny predeterminat en qualsevol moment.
Tingueu en compte que el sistema desarà l'estat d'alguns elements de la vista, com ara el contingut de l'EditText.
2.2 Restaura l'estat de la instància d'activitat a onCreate()
Un cop hàgiu desat l'estat de la instància de l'activitat, també heu de restaurar-lo quan es torni a crear l'activitat. Podeu fer-ho a onCreate() o implementant la devolució de trucada onRestoreInstanceState(), que es crida després de onStart() després de crear l'activitat.
La majoria de les vegades, el millor lloc per restaurar l'estat de l'activitat és onCreate(), per garantir que la interfície d'usuari, inclòs l'estat, estigui disponible el més aviat possible. De vegades és convenient fer-ho a onRestoreInstanceState() després d'haver fet tota la inicialització, o permetre que les subclasses decideixin si utilitzen la vostra implementació predeterminada.
- Al mètode onCreate(), després d'inicialitzar les variables View amb findViewById(), afegiu una prova per assegurar-vos que savedInstanceState no sigui nul.
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
// Restore the state.
if (savedInstanceState != null) {
}
Quan es crea la vostra activitat, el sistema passa el paquet d'estat a onCreate() com a únic argument. La primera vegada que es crida a onCreate() i s'inicia l'aplicació, el paquet és nul; no hi ha cap estat la primera vegada que s'inicia l'aplicació. Les trucades posteriors a onCreate() tenen un paquet emplenat amb les dades que heu emmagatzemat a onSaveInstanceState().
- Dins d'aquesta comprovació, traieu la visibilitat actual (vertadera o falsa) del paquet amb la clau "reply_visible".
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
}
- Afegiu una prova a sota d'aquesta línia anterior per a la variable isVisible.
if (isVisible) {
}
Si hi ha una clau reply_visible al paquet d'estats (i, per tant, isVisible és cert), haureu de restaurar l'estat.
- Dins de la prova isVisible, feu visible la capçalera.
mReplyHeadTextView.setVisibility(View.VISIBLE);
- Obteniu el missatge de resposta de text del paquet amb la clau "reply_text" i configureu la resposta TextView per mostrar aquesta cadena.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
- Feu que la resposta TextView també sigui visible:
mReplyTextView.setVisibility(View.VISIBLE);
- Executeu l'aplicació. Proveu de girar el dispositiu o l'emulador per assegurar-vos que el missatge de resposta (si n'hi ha) es mantingui a la pantalla després de recrear l'activitat.
Codi de solució de la tasca 2
Els fragments de codi següents mostren el codi de solució per a aquesta tasca.
Activitat principal
Els fragments de codi següents mostren el codi afegit a MainActivity, però no tota la classe.
El mètode onSaveInstanceState():
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// If the heading is visible, message needs to be saved.
// Otherwise we're still using default layout.
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
outState.putString("reply_text",
mReplyTextView.getText().toString());
}
}
El mètode onCreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
// Restore the saved state.
// See onSaveInstanceState() for what gets saved.
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
// Show both the header and the message views. If isVisible is
// false or missing from the bundle, use the default layout.
if (isVisible) {
mReplyHeadTextView.setVisibility(View.VISIBLE);
mReplyTextView.setText(savedInstanceState
.getString("reply_text"));
mReplyTextView.setVisibility(View.VISIBLE);
}
}
}
El projecte complet:
Projecte Android Studio: TwoActivitiesLifecycle
5. Codificació
Repte: creeu una aplicació senzilla de llista de compres amb una activitat principal per a la llista que l'usuari està creant i una segona activitat per a una llista d'articles de compres habituals.
- L'activitat principal hauria de contenir la llista a construir, que hauria d'estar formada per deu elements TextView buits.
- Un botó Afegeix un article a l'activitat principal inicia una segona activitat que conté una llista d'articles de compra habituals (Formatge, Arròs, Pomes, etc.). Utilitzeu els elements del botó per mostrar els elements.
- L'elecció d'un element retorna l'usuari a l'activitat principal i actualitza un TextView buit per incloure l'element escollit.
Utilitzeu una Intenció per passar informació d'una activitat a una altra. Assegureu-vos que l'estat actual de la llista de la compra es desa quan l'usuari giri el dispositiu.
6. Resum
- El cicle de vida de l'activitat és un conjunt d'estats pels quals migra una activitat, començant quan es crea per primera vegada i acaba quan el sistema Android recupera els recursos per a aquesta activitat.
- A mesura que l'usuari navega d'una activitat a una altra i dins i fora de la vostra aplicació, cada activitat es mou entre estats del cicle de vida de l'activitat.
- Cada estat del cicle de vida de l'activitat té un mètode de devolució de trucada corresponent que podeu substituir a la vostra classe d'activitat.
- Els mètodes del cicle de vida són onCreate(), onStart(), onPause(), onRestart(), onResume(), onStop(), onDestroy().
- La substitució d'un mètode de devolució de trucada del cicle de vida us permet afegir un comportament que es produeix quan la vostra activitat passa a aquest estat.
- Pots afegir mètodes d'anul·lació d'esquelet a les teves classes a Android Studio amb Codi > Anul·lació.
- Els canvis de configuració del dispositiu, com ara la rotació, fan que l'activitat es destrueixi i es torni a crear com si fos nova.
- Una part de l'estat de l'activitat es conserva en un canvi de configuració, inclosos els valors actuals dels elements EditText. Per a la resta de dades, les heu de desar explícitament.
- Desa l'estat de la instància de l'activitat al mètode onSaveInstanceState().
- Les dades d'estat de la instància s'emmagatzemen com a parells clau/valor simples en un paquet. Utilitzeu els mètodes del paquet per introduir i recuperar dades del paquet.
- Restaura l'estat de la instància a onCreate(), que és la manera preferida, o onRestoreInstanceState(). Enrere
1. Benvinguts
Aquest laboratori pràctic forma part de la Unitat 1: Iniciació al curs Fonaments per a desenvolupadors d'Android (versió 2). Treureu el màxim profit d'aquest curs si treballeu els laboratoris de codificació en seqüència:
- Per obtenir la llista completa de codelabs del curs, vegeu Codelabs for Android Developer Fundamentals (V2).
- Per obtenir més informació sobre el curs, inclosos els enllaços a tots els capítols conceptuals, aplicacions i diapositives, consulteu Fonaments per a desenvolupadors d'Android (versió 2).
Introducció
En aquesta pràctica aprendràs més sobre el cicle de vida de l'activitat. El cicle de vida és el conjunt d'estats en què pot estar una activitat durant tota la seva vida útil, des del moment en què es crea fins al moment en què es destrueix i el sistema recupera els seus recursos. A mesura que un usuari navega entre les activitats de la vostra aplicació (així com dins i fora de la vostra aplicació), les activitats passen entre diferents estats en els seus cicles de vida.
Cada etapa del cicle de vida d'una activitat té un mètode de devolució de trucada corresponent: onCreate(), onStart(), onPause(), etc. Quan una activitat canvia d'estat, s'invoca el mètode de devolució de trucada associat. Ja heu vist un d'aquests mètodes: onCreate(). En anul·lar qualsevol dels mètodes de devolució de trucada del cicle de vida a les classes d'activitat, podeu canviar el comportament predeterminat de l'activitat en resposta a les accions de l'usuari o del sistema.
L'estat de l'activitat també pot canviar en resposta als canvis de configuració del dispositiu, per exemple, quan l'usuari gira el dispositiu de vertical a horitzontal. Quan es produeixen aquests canvis de configuració, l'activitat es destrueix i es recrea en el seu estat predeterminat i l'usuari pot perdre la informació que ha introduït a l'activitat. Per evitar confondre els usuaris, és important que desenvolupeu la vostra aplicació per evitar pèrdues de dades inesperades. Més endavant, en aquesta pràctica, experimenteu amb els canvis de configuració i apreneu a preservar l'estat d'una activitat en resposta als canvis de configuració del dispositiu i altres esdeveniments del cicle de vida de l'activitat.
En aquesta pràctica, afegiu declaracions de registre a l'aplicació TwoActivities i observeu els canvis del cicle de vida de l'activitat mentre feu servir l'aplicació. A continuació, comenceu a treballar amb aquests canvis i a explorar com gestionar l'entrada de l'usuari en aquestes condicions.
Requisits previs
Hauries de ser capaç de:
- Creeu i executeu un projecte d'aplicació a Android Studio .
- Afegiu declaracions de registre a la vostra aplicació i visualitzeu aquests registres al panell de Logcat.
- Comprendre i treballar amb una activitat i una intenció, i sentir-se còmode interactuant amb ells.
El que aprendràs
- Com funciona el cicle de vida de l'activitat.
- Quan una activitat comença, s'atura, s'atura i es destrueix.
- Sobre els mètodes de devolució de trucada del cicle de vida associats als canvis d'activitat.
- L'efecte de les accions (com ara els canvis de configuració) que poden provocar esdeveniments del cicle de vida de l'activitat.
- Com conservar l'estat de l'activitat durant els esdeveniments del cicle de vida.
Què faràs
- Afegiu codi a l'aplicació TwoActivities de la pràctica anterior per implementar les diverses devolucions de trucada del cicle de vida de l'activitat per incloure declaracions de registre.
- Observeu els canvis d'estat a mesura que s'executa l'aplicació i mentre interactueu amb cada activitat de la vostra aplicació.
- Modifiqueu la vostra aplicació per mantenir l'estat d'instància d'una activitat que es recrea de manera inesperada en resposta al comportament de l'usuari o al canvi de configuració al dispositiu.
2. Visió general de l'aplicació
En aquesta pràctica s'afegeix a l'aplicació TwoActivities . L'aplicació té un aspecte i un comportament aproximadament igual que a l'últim laboratori de codificació. Conté dues implementacions d'Activity i ofereix a l'usuari la possibilitat d'enviar entre elles. Els canvis que feu a l'aplicació en aquesta pràctica no afectaran el seu comportament visible dels usuaris.
3. 3. Tasca 1: Afegiu devolucions de trucada del cicle de vida a TwoActivities
En aquesta tasca implementareu tots els mètodes de devolució del cicle de vida de l'activitat per imprimir missatges al logcat quan s'invoquin aquests mètodes. Aquests missatges de registre us permetran veure quan el cicle de vida de l'activitat canvia d'estat i com aquests canvis d'estat del cicle de vida afecten la vostra aplicació mentre s'executa.
1.1 (Opcional) Copia el projecte TwoActivities
Per a les tasques d'aquesta pràctica, modificareu el projecte TwoActivities existent que heu creat a l'última pràctica. Si preferiu mantenir intacte el projecte anterior de TwoActivities, seguiu els passos de l'Apèndix: Utilitats per fer una còpia del projecte.
1.2 Implementar devolucions de trucada a MainActivity
- Obriu el projecte TwoActivities a Android Studio i obriu MainActivity al panell Projecte > Android.
- Al mètode onCreate(), afegiu les instruccions de registre següents:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
- Afegiu una substitució per a la devolució de trucada onStart(), amb una declaració al registre d'aquest esdeveniment:
@Override
public void onStart(){
super.onStart();
Log.d(LOG_TAG, "onStart");
}
Per obtenir una drecera, seleccioneu Codi > Anul·lació de mètodes a Android Studio. Apareix un diàleg amb tots els mètodes possibles que podeu substituir a la vostra classe. Si escolliu un o més mètodes de devolució de trucada de la llista, s'insereix una plantilla completa per a aquests mètodes, inclosa la trucada necessària a la superclasse.
- Utilitzeu el mètode onStart() com a plantilla per implementar les devolucions de trucada del cicle de vida onPause(), onRestart(), onResume(), onStop() i onDestroy().
Tots els mètodes de devolució de trucada tenen les mateixes signatures (excepte el nom). Si copieu i enganxeu onStart() per crear aquests altres mètodes de devolució de trucada, no us oblideu d'actualitzar el contingut per trucar al mètode correcte a la superclasse i registrar el mètode correcte.
- Executeu la vostra aplicació.
- Feu clic a la pestanya Logcat a la part inferior d'Android Studio per mostrar el panell Logcat. Hauríeu de veure tres missatges de registre que mostren els tres estats del cicle de vida pels quals ha transigut l'activitat quan va començar:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume
1.3 Implementar devolucions de trucada del cicle de vida a SecondActivity
Ara que heu implementat els mètodes de devolució del cicle de vida per a MainActivity, feu el mateix per a SecondActivity.
- Obriu SecondActivity.
- A la part superior de la classe, afegiu una constant per a la variable LOG_TAG:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
- Afegiu les devolucions de trucada del cicle de vida i les declaracions de registre a la segona activitat. (Podeu copiar i enganxar els mètodes de devolució de trucada des de MainActivity.)
- Afegiu una instrucció de registre al mètode returnReply() just abans del mètode finish():
Log.d(LOG_TAG, "End SecondActivity");
1.4 Observeu el registre mentre s'executa l'aplicació**
- Executeu la vostra aplicació.
- Feu clic a la pestanya Logcat a la part inferior d'Android Studio per mostrar el panell Logcat.
- Introduïu Activitat al quadre de cerca. El logcat d'Android pot ser molt llarg i desordenat. Com que la variable LOG_TAG de cada classe conté les paraules MainActivity o SecondActivity, aquesta paraula clau us permet filtrar el registre només per les coses que us interessen.
Experimenteu amb la vostra aplicació i tingueu en compte que els esdeveniments del cicle de vida que es produeixen en resposta a diferents accions. En particular, proveu aquestes coses:
- Utilitza l'aplicació amb normalitat (envia un missatge, respon amb un altre missatge).
- Feu servir el botó Enrere per tornar de la segona activitat a l'activitat principal.
- Utilitzeu la fletxa amunt de la barra de l'aplicació per tornar de la segona activitat a l'activitat principal.
- Gireu el dispositiu tant a l'activitat principal com a la segona en diferents moments de la vostra aplicació i observeu què passa al *registre i a la pantalla.
- Premeu el botó de visió general (el botó quadrat a la dreta d'Inici) i tanqueu l'aplicació (toqueu la X).
- Torna a la pantalla d'inici i reinicia l'aplicació.
CONSELL: si esteu executant la vostra aplicació en un emulador, podeu simular la rotació amb Control+F11 o Control+Funció+F11.
Codi de solució de la tasca 1
Els fragments de codi següents mostren el codi de solució per a la primera tasca.
Activitat principal
Els fragments de codi següents mostren el codi afegit a MainActivity, però no tota la classe.
El mètode onCreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Log the start of the onCreate() method.
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
}
Altres mètodes de cicle de vida:
@Override
protected void onStart() {
super.onStart();
Log.d(LOG_TAG, "onStart");
}
@Override
protected void onPause() {
super.onPause();
Log.d(LOG_TAG, "onPause");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(LOG_TAG, "onRestart");
}
@Override
protected void onResume() {
super.onResume();
Log.d(LOG_TAG, "onResume");
}
@Override
protected void onStop() {
super.onStop();
Log.d(LOG_TAG, "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(LOG_TAG, "onDestroy");
}
Segona activitat
Els fragments de codi següents mostren el codi afegit a SecondActivity, però no tota la classe.
A la part superior de la classe SecondActivity:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
El mètode returnReply():
public void returnReply(View view) {
String reply = mReply.getText().toString();
Intent replyIntent = new Intent();
replyIntent.putExtra(EXTRA_REPLY, reply);
setResult(RESULT_OK, replyIntent);
Log.d(LOG_TAG, "End SecondActivity");
finish();
}
Altres mètodes de cicle de vida:
El mateix que per a MainActivity, a dalt.
4. 4. Tasca 2: desar i restaurar l'estat de la instància d'activitat
Depenent dels recursos del sistema i del comportament dels usuaris, cada activitat de la vostra aplicació es pot destruir i reconstruir amb molta més freqüència del que podríeu pensar.
És possible que hàgiu notat aquest comportament a l'última secció quan vau girar el dispositiu o l'emulador. Girar el dispositiu és un exemple de canvi de configuració del dispositiu. Tot i que la rotació és la més habitual, tots els canvis de configuració fan que l'activitat actual es destrueixi i es torni a crear com si fos nova. Si no tens en compte aquest comportament al teu codi, quan es produeix un canvi de configuració, el disseny de l'activitat pot tornar a l'aspecte predeterminat i als valors inicials, i els usuaris poden perdre el seu lloc, les seves dades o l'estat del seu progrés a la teva aplicació.
L'estat de cada activitat s'emmagatzema com un conjunt de parells clau/valor en un objecte Bundle anomenat estat de la instància de l'activitat. El sistema desa la informació d'estat predeterminada al paquet d'estat de la instància just abans que s'atura l'activitat i passa aquest paquet a la nova instància d'activitat per restaurar-lo.
Per evitar que es perdin dades en una activitat quan es destrueix i es recrea de manera inesperada, cal que implementeu el mètode onSaveInstanceState(). El sistema crida aquest mètode a la vostra activitat (entre onPause() i onStop()) quan hi ha la possibilitat que l'activitat es destrueixi i es torni a crear.
Les dades que deseu a l'estat de la instància són específiques només d'aquesta instància d'aquesta Activitat específica durant la sessió de l'aplicació actual. Quan atureu i reinicieu una sessió d'aplicació nova, l'estat de la instància d'activitat es perd i l'activitat torna al seu aspecte predeterminat. Si necessiteu desar dades d'usuari entre sessions d'aplicacions, utilitzeu preferències compartides o una base de dades. Aprèn sobre tots dos en una pràctica posterior.
2.1 Deseu l'estat de la instància d'activitat amb onSaveInstanceState()
És possible que hàgiu notat que girar el dispositiu no afecta en absolut l'estat de la segona activitat. Això es deu al fet que el segon disseny i estat de l'activitat es generen a partir del disseny i la intenció que l'ha activat. Fins i tot si es recrea l'activitat, la intenció encara hi és i les dades d'aquesta intenció encara es fan servir cada vegada que es crida al mètode onCreate() de la segona activitat.
A més, és possible que observeu que a cada activitat, qualsevol text que heu escrit als elements EditText del missatge o de la resposta es conserva fins i tot quan es gira el dispositiu. Això es deu al fet que la informació d'estat d'alguns dels elements de Visualització del vostre disseny es desa automàticament a través dels canvis de configuració, i el valor actual d'un EditText és un d'aquests casos.
Per tant, l'únic estat d'activitat que us interessa són els elements TextView per a la capçalera de resposta i el text de resposta a l'activitat principal. Tots dos elements de TextView són invisibles per defecte; només apareixen quan envieu un missatge a l'activitat principal des de la segona activitat.
En aquesta tasca, afegiu codi per preservar l'estat d'instància d'aquests dos elements TextView mitjançant onSaveInstanceState().
- Obriu MainActivity.
- Afegiu aquesta implementació d'esquelet d'onSaveInstanceState() a l'activitat o utilitzeu Codi > Mètodes de substitució per inserir una substitució d'esquelet.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
- Comproveu si la capçalera és visible actualment i, si és així, poseu aquest estat de visibilitat a l'estat Bundle amb el mètode putBoolean() i la clau "reply_visible".
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
}
Recordeu que la capçalera i el text de la resposta es marquen com a invisibles fins que hi hagi una resposta de la segona activitat. Si la capçalera és visible, hi ha dades de resposta que s'han de desar. Tingueu en compte que només ens interessa aquest estat de visibilitat: no cal desar el text real de la capçalera, perquè aquest text no canvia mai.
- Dins d'aquesta mateixa comprovació, afegiu el text de resposta al paquet.
outState.putString("reply_text",mReplyTextView.getText().toString());
Si la capçalera és visible, podeu suposar que el missatge de resposta també és visible. No cal que proveu ni deseu l'estat de visibilitat actual del missatge de resposta. Només el text real del missatge entra al paquet d'estat amb la clau "reply_text".
Deseu l'estat només d'aquells elements de visualització que poden canviar després de crear l'activitat. Els altres elements de visualització de la vostra aplicació (el text Edit, el botó) es poden tornar a crear des del disseny predeterminat en qualsevol moment.
Tingueu en compte que el sistema desarà l'estat d'alguns elements de la vista, com ara el contingut de l'EditText.
2.2 Restaura l'estat de la instància d'activitat a onCreate()
Un cop hàgiu desat l'estat de la instància de l'activitat, també heu de restaurar-lo quan es torni a crear l'activitat. Podeu fer-ho a onCreate() o implementant la devolució de trucada onRestoreInstanceState(), que es crida després de onStart() després de crear l'activitat.
La majoria de les vegades, el millor lloc per restaurar l'estat de l'activitat és onCreate(), per garantir que la interfície d'usuari, inclòs l'estat, estigui disponible tan aviat com sigui possible. De vegades és convenient fer-ho a onRestoreInstanceState() després d'haver fet tota la inicialització, o permetre que les subclasses decideixin si utilitzen la vostra implementació predeterminada.
- Al mètode onCreate(), després d'inicialitzar les variables View amb findViewById(), afegiu una prova per assegurar-vos que savedInstanceState no sigui nul.
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
// Restore the state.
if (savedInstanceState != null) {
}
Quan es crea la vostra activitat, el sistema passa el paquet d'estat a onCreate() com a únic argument. La primera vegada que es crida a onCreate() i s'inicia l'aplicació, el paquet és nul; no hi ha cap estat la primera vegada que s'inicia l'aplicació. Les trucades posteriors a onCreate() tenen un paquet emplenat amb les dades que heu emmagatzemat a onSaveInstanceState().
- Dins d'aquesta comprovació, traieu la visibilitat actual (vertadera o falsa) del paquet amb la clau "reply_visible".
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
}
- Afegiu una prova a sota d'aquesta línia anterior per a la variable isVisible.
if (isVisible) {
}
Si hi ha una clau reply_visible al paquet d'estats (i, per tant, isVisible és cert), haureu de restaurar l'estat.
- Dins de la prova isVisible, feu visible la capçalera.
mReplyHeadTextView.setVisibility(View.VISIBLE);
- Obteniu el missatge de resposta de text del paquet amb la clau "reply_text" i configureu la resposta TextView per mostrar aquesta cadena.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
- Feu que la resposta TextView també sigui visible:
mReplyTextView.setVisibility(View.VISIBLE);
- Executeu l'aplicació. Proveu de girar el dispositiu o l'emulador per assegurar-vos que el missatge de resposta (si n'hi ha) es mantingui a la pantalla després de recrear l'activitat.
Codi de solució de la tasca 2
Els fragments de codi següents mostren el codi de solució per a aquesta tasca.
Activitat principal
Els fragments de codi següents mostren el codi afegit a MainActivity, però no tota la classe.
El mètode onSaveInstanceState():
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// If the heading is visible, message needs to be saved.
// Otherwise we're still using default layout.
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
outState.putString("reply_text",
mReplyTextView.getText().toString());
}
}
El mètode onCreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
// Restore the saved state.
// See onSaveInstanceState() for what gets saved.
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
// Show both the header and the message views. If isVisible is
// false or missing from the bundle, use the default layout.
if (isVisible) {
mReplyHeadTextView.setVisibility(View.VISIBLE);
mReplyTextView.setText(savedInstanceState
.getString("reply_text"));
mReplyTextView.setVisibility(View.VISIBLE);
}
}
}
El projecte complet:
Projecte Android Studio: TwoActivitiesLifecycle
5. Codificació
Repte: creeu una aplicació senzilla de llista de compres amb una activitat principal per a la llista que l'usuari està creant i una segona activitat per a una llista d'articles de compres habituals.
- L'activitat principal hauria de contenir la llista per crear, que hauria d'estar formada per deu elements TextView buits.
- Un botó Afegeix un article a l'activitat principal inicia una segona activitat que conté una llista d'articles de compra habituals (Formatge, Arròs, Pomes, etc.). Utilitzeu elements del botó per mostrar els elements.
- L’elecció d’un element retorna l’usuari a l’activitat principal i actualitza una vista de text buida per incloure l’element escollit.
Utilitzeu una intenció per passar informació d’una activitat a una altra. Assegureu -vos que l'estat actual de la llista de compres es guardi quan l'usuari gira el dispositiu.
6. Resum
- El cicle de vida de l’activitat és un conjunt d’estats que una activitat migra, començant quan es crea per primera vegada i s’acaba quan el sistema Android recupera els recursos per a aquesta activitat.
- A mesura que l’usuari navega d’una activitat a una altra i dins i fora de la vostra aplicació, cada activitat es mou entre els estats del cicle de vida de l’activitat.
- Cada estat del cicle de vida de l’activitat té un mètode de devolució corresponent que podeu substituir a la vostra classe d’activitat.
- Els mètodes del cicle de vida són onCreate (), onStart (), onPause (), onRestart (), onResume (), onStop (), onDestroy ().
- Superar un mètode de devolució del cicle de vida permet afegir un comportament que es produeix quan la vostra activitat es transmet a aquest estat.
- Podeu afegir mètodes de substitució d'esquelet a les vostres classes a Android Studio amb codi> substitució.
- Els canvis de configuració del dispositiu com ara la rotació es tradueixen en la destrucció i recreada de l'activitat com si fos nou.
- Una part de l'estat d'activitat es conserva en un canvi de configuració, inclosos els valors actuals dels elements d'EditText. Per a la resta de dades, heu de desar explícitament aquestes dades.
- Desa l'estat de la instància d'activitat al mètode OnsaveInstanceState ().
- Les dades d’estat d’instància s’emmagatzemen com a parelles de clau/valor simples en un paquet. Utilitzeu els mètodes del paquet per posar les dades i tornar a treure les dades del paquet.
- Restaureu l'estat d'instància a onCreate (), que és la manera preferida, o onrestoreinstanceState (). Enrere
1. Benvingut
Aquesta pràctica CodeLab forma part de la unitat 1: iniciar -se en el curs Fonaments de desenvolupadors d'Android (versió 2). Obtindreu el màxim valor d’aquest curs si treballeu a través dels CodeLabs en seqüència:
- Per obtenir la llista completa de CodeLabs al curs, vegeu CodeLabs per als fonaments de desenvolupadors d'Android (V2).
- Per obtenir més informació sobre el curs, inclosos els enllaços a tots els capítols de concepte, aplicacions i diapositives, vegeu Fonaments de desenvolupadors d'Android (versió 2).
Introducció
En aquesta pràctica, obtindreu més informació sobre el cicle de vida de l’activitat. El cicle de vida és el conjunt d’estats que pot ser una activitat durant tota la seva vida, des de quan es crea fins a la destrucció i el sistema recupera els seus recursos. A mesura que l’usuari navega entre activitats de la vostra aplicació (així com dins i fora de la vostra aplicació), la transició d’activitats entre diferents estats en els seus cicles de vida.
Cada etapa del cicle de vida d’una activitat té un mètode de devolució corresponent: onCreate (), onStart (), onPause (), etc. Quan una activitat canvia d’estat, s’invoca el mètode de devolució associat. Ja heu vist un d'aquests mètodes: onCreate (). En substituir qualsevol dels mètodes de devolució del cicle de vida de les vostres classes d’activitat, podeu canviar el comportament predeterminat de l’activitat en resposta a les accions d’usuari o sistema.
L’estat d’activitat també pot canviar com a resposta als canvis de configuració del dispositiu, per exemple quan l’usuari gira el dispositiu des del retrat al paisatge. Quan es produeixen aquests canvis de configuració, l’activitat es destrueix i es recreà en el seu estat predeterminat i l’usuari pot perdre informació que han introduït a l’activitat. Per evitar confondre els usuaris, és important que desenvolupeu la vostra aplicació per evitar pèrdues inesperades de dades. Més endavant en aquesta pràctica, experimenteu amb canvis de configuració i apreneu a preservar l’estat d’una activitat en resposta als canvis de configuració del dispositiu i altres esdeveniments del cicle de vida de l’activitat.
En aquesta pràctica, afegiu declaracions de registre a l’aplicació Twoactivities i observeu els canvis de cicle de vida de l’activitat a mesura que utilitzeu l’aplicació. A continuació, comenceu a treballar amb aquests canvis i a explorar com gestionar l’entrada dels usuaris en aquestes condicions.
Requisits previs
Hauríeu de ser capaços de:
- Creeu i executeu un projecte d'aplicacions a Android Studio .
- Afegiu declaracions de registre a la vostra aplicació i visualitzeu aquests registres al panell de registre.
- Comprendre i treballar amb una activitat i una intenció i estar còmode interactuant amb ells.
El que aprendràs
- Com funciona el cicle de vida de l’activitat.
- Quan s’inicia una activitat, s’atura, s’atura i es destrueix.
- Sobre els mètodes de trucada de cicle de vida associats als canvis d’activitat.
- L’efecte de les accions (com ara els canvis de configuració) que poden donar lloc a esdeveniments del cicle de vida de l’activitat.
- Com conservar l'estat de l'activitat entre els esdeveniments del cicle de vida.
Què faràs
- Afegiu codi a l’aplicació Twoactivities de la pràctica anterior per implementar les diverses devolucions de cicle de vida de l’activitat per incloure les declaracions de registre.
- Observeu l'estat canvia a mesura que s'executa l'aplicació i mentre interactueu amb cada activitat de la vostra aplicació.
- Modifiqueu la vostra aplicació per conservar l’estat d’instància d’una activitat que es recreà inesperadament en resposta al comportament de l’usuari o al canvi de configuració del dispositiu.
2. Visió general de l'aplicació
En aquesta pràctica s’afegeix a l’aplicació Twoactivities . L’aplicació es veu i es comporta aproximadament el mateix que ho va fer a l’últim CodeLab. Conté dues implementacions d’activitats i proporciona a l’usuari la possibilitat d’enviar entre elles. Els canvis que feu a l'aplicació en aquesta pràctica no afectaran el seu comportament visible dels usuaris.
3. 3. Tasca 1: Afegiu les trucades del cicle de vida a dues activitats
En aquesta tasca implementareu tots els mètodes de devolució del cicle de vida de l’activitat per imprimir missatges a logCAT quan s’invoca aquests mètodes. Aquests missatges de registre us permetran veure quan el cicle de vida de l’activitat canvia d’estat i com afecten els canvis d’estat del cicle de vida a mesura que s’executa.
1.1 (opcional) Copieu el projecte de dues activitats
Per a les tasques d'aquesta pràctica, modificareu el projecte de dues activitats existent que heu creat en l'últim pràctic. Si preferiu mantenir intacte el projecte de dues activitats anteriors, seguiu els passos a l’apèndix: Utilitats per fer una còpia del projecte.
1.2 Implementar les trucades a MainActivity
- Obriu el projecte de dues activitats a Android Studio i obriu MainActivity al Projecte> Android Pane.
- Al mètode onCreate (), afegiu les afirmacions de registre següents:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
- Afegiu una substitució per a la devolució de devolució (), amb una declaració al registre d'aquest esdeveniment:
@Override
public void onStart(){
super.onStart();
Log.d(LOG_TAG, "onStart");
}
Per a una drecera, seleccioneu Codi> Mètodes de substitució a Android Studio. Apareix un diàleg amb tots els mètodes possibles que podeu substituir a la vostra classe. L’elecció d’un o més mètodes de devolució de la llista insereix una plantilla completa per a aquests mètodes, inclosa la trucada necessària a la superclasse.
- Utilitzeu el mètode onStart () com a plantilla per implementar les devolució de la vida onPause (), OnRestart (), OnResume (), OnStop () i OnDestroy ()
Tots els mètodes de devolució tenen les mateixes signatures (excepte el nom). Si copieu i enganxeu OnStart () per crear aquests altres mètodes de trucada, no us oblideu d’actualitzar el contingut per trucar al mètode adequat a la superclasse i registrar el mètode correcte.
- Executeu la vostra aplicació.
- Feu clic a la pestanya Logcat a la part inferior d'Android Studio per mostrar el panell Logcat. Hauríeu de veure tres missatges de registre que mostren els tres estats del cicle de vida que l’activitat ha passat a l’hora de començar:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume
1.3 Implementar les trucades del cicle de vida a SeconActivity
Ara que heu implementat els mètodes de devolució del cicle de vida per a MainActivity, feu el mateix per a SeconActivity.
- Obriu la segona activitat.
- A la part superior de la classe, afegiu una constant per a la variable log_tag:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
- Afegiu els cicles de vida i les declaracions de registre a la segona activitat. (Podeu copiar i enganxar els mètodes de devolució de MainActivity.)
- Afegiu una instrucció de registre al mètode returnReply () just abans del mètode Final ():
Log.d(LOG_TAG, "End SecondActivity");
1.4 Observeu el registre a mesura que s'executa l'aplicació **
- Executeu la vostra aplicació.
- Feu clic a la pestanya Logcat a la part inferior d'Android Studio per mostrar el panell Logcat.
- Introduïu l'activitat al quadre de cerca. El Logcat d'Android pot ser molt llarg i desordenat. Com que la variable log_tag de cada classe conté les paraules MainActivity o SeconActivity, aquesta paraula clau us permet filtrar el registre només per a les coses que us interessa.
Experimenteu mitjançant la vostra aplicació i tingueu en compte que els esdeveniments del cicle de vida que es produeixen en resposta a diferents accions. En particular, proveu aquestes coses:
- Utilitzeu l'aplicació normalment (envieu un missatge, responeu amb un altre missatge).
- Utilitzeu el botó enrere per tornar de la segona activitat a la principal activitat.
- Utilitzeu la fletxa amunt de la barra d'aplicacions per tornar de la segona activitat a la principal activitat.
- Gireu el dispositiu tant a la principal com a la segona activitat en diferents moments de la vostra aplicació i observeu què passa a * el registre i a la pantalla.
- Premeu el botó de visió general (el botó quadrat a la dreta de casa) i tanqueu l'aplicació (toqueu la X).
- Torneu a la pantalla d'inici i reinicieu l'aplicació.
Consell: si executeu la vostra aplicació en un emulador, podeu simular la rotació amb Control+F11 o Control+Function+F11.
Codi de solució de la tasca 1
Els fragments de codi següents mostren el codi de solució per a la primera tasca.
Mainactivitat
Els fragments de codi següents mostren el codi afegit a MainActivity, però no a tota la classe.
El mètode onCreate ():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Log the start of the onCreate() method.
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
}
Els altres mètodes del cicle de vida:
@Override
protected void onStart() {
super.onStart();
Log.d(LOG_TAG, "onStart");
}
@Override
protected void onPause() {
super.onPause();
Log.d(LOG_TAG, "onPause");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(LOG_TAG, "onRestart");
}
@Override
protected void onResume() {
super.onResume();
Log.d(LOG_TAG, "onResume");
}
@Override
protected void onStop() {
super.onStop();
Log.d(LOG_TAG, "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(LOG_TAG, "onDestroy");
}
Secondactivitat
Els fragments de codi següents mostren el codi afegit a SeconActivity, però no a tota la classe.
A la part superior de la classe de SeconActivity:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
El mètode returnReply ():
public void returnReply(View view) {
String reply = mReply.getText().toString();
Intent replyIntent = new Intent();
replyIntent.putExtra(EXTRA_REPLY, reply);
setResult(RESULT_OK, replyIntent);
Log.d(LOG_TAG, "End SecondActivity");
finish();
}
Els altres mètodes del cicle de vida:
Igual que per a MainActivity, més amunt.
4. 4. Tasca 2: Desar i restaurar l’estat d’instància d’activitat
Segons els recursos del sistema i el comportament dels usuaris, cada activitat de la vostra aplicació pot ser destruïda i reconstruïda amb més freqüència del que podríeu pensar.
És possible que hagueu notat aquest comportament a l’última secció quan heu girat el dispositiu o l’emulador. Rotar el dispositiu és un exemple de canvi de configuració del dispositiu. Tot i que la rotació és la més comuna, tots els canvis de configuració donen lloc a que l’activitat actual sigui destruïda i recreada com si fos nova. Si no teniu en compte aquest comportament al vostre codi, quan es produeix un canvi de configuració, el disseny de l’activitat pot tornar a la seva aparença predeterminada i valors inicials, i els usuaris poden perdre el seu lloc, les seves dades o l’estat del seu progrés la vostra aplicació.
L’estat de cada activitat s’emmagatzema com a conjunt de parells de claus/valor en un objecte de paquet anomenat Estat d’instància d’activitat. El sistema estalvia informació d’estat predeterminat al paquet d’estat d’instància just abans de l’aturada de l’activitat i passa aquest paquet a la nova instància d’activitat per restaurar.
Per evitar perdre les dades en una activitat quan es destrueix i es recrea inesperadament, heu d’implementar el mètode OnSaveInstanceState (). El sistema anomena aquest mètode a la vostra activitat (entre onPause () i OnStop ()) quan hi ha la possibilitat que l'activitat es pugui destruir i recrear.
Les dades que guardeu en l’estat d’instància són específiques només per a aquesta instància d’aquesta activitat específica durant la sessió d’aplicació actual. Quan atureu i reinicieu una nova sessió d'aplicacions, l'estat de la instància d'activitat es perd i l'activitat torna a la seva aparença per defecte. Si necessiteu desar les dades de l’usuari entre les sessions d’aplicacions, utilitzeu preferències compartides o una base de dades. Apreneu sobre tots dos en una pràctica posterior.
2.1 Desa l'estat de la instància d'activitat amb OnSaveInstanceState ()
És possible que hagueu notat que girar el dispositiu no afecta en absolut l’estat de la segona activitat. Això es deu al fet que la segona disposició i estat de l’activitat es generen a partir del disseny i la intenció que l’activessin. Tot i que l’activitat es recreà, la intenció encara hi és i les dades en aquesta intenció encara s’utilitzen cada vegada que s’anomena el mètode oncreate () de la segona activitat.
A més, podeu notar que en cada activitat, qualsevol text que heu escrit a Missatge o Respon alements EditText es conserva fins i tot quan es gira el dispositiu. Això es deu al fet que la informació estatal d’alguns dels elements de vista del disseny es desarà automàticament en els canvis de configuració i el valor actual d’un editText és un d’aquests casos.
Per tant, l'únic estat d'activitat que us interessa són els elements de TextView per a la capçalera de resposta i el text de resposta a l'activitat principal. Els dos elements de TextView són invisibles per defecte; Només apareixen un cop envieu un missatge a l’activitat principal de la segona activitat.
En aquesta tasca, afegiu codi per preservar l'estat de la instància d'aquests dos elements de TextView mitjançant OnsaveInstanCeState ().
- Obert MainActivitat.
- Afegiu aquesta implementació d'esquelet de OnSaveInstanceState () a l'activitat o utilitzeu el codi> Substituir mètodes per inserir una substitució d'esquelet.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
- Comproveu si actualment la capçalera és visible i, si és així, poseu aquest estat de visibilitat al paquet d’estat amb el mètode PutBoolean () i la clau "Respon_visible".
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
}
Recordeu que l’encapçalament de la resposta i el text estan marcats invisibles fins que hi hagi una resposta de la segona activitat. Si la capçalera és visible, hi ha dades de resposta que cal desar. Tingueu en compte que només ens interessa aquest estat de visibilitat: el text real de la capçalera no s'ha de desar, perquè aquest text no canvia mai.
- Dins d'aquesta mateixa comprovació, afegiu el text de resposta al paquet.
outState.putString("reply_text",mReplyTextView.getText().toString());
Si la capçalera és visible, podeu suposar que el missatge de resposta en si també és visible. No cal provar ni guardar l'estat de visibilitat actual del missatge de resposta. Només el text real del missatge entra al paquet d'estat amb la clau "Respon_text".
Estalvieu l’estat només d’aquells elements de vista que poden canviar després de la creació de l’activitat. Els altres elements de vista de la vostra aplicació (el botó EditText, el botó) es poden recrear des de la disposició predeterminada en qualsevol moment.
Tingueu en compte que el sistema estalviarà l'estat d'alguns elements de vista, com ara el contingut de l'EditText.
2.2 Restaureu l'estat d'instància d'activitat a onCreate ()
Un cop hagueu guardat l’estat d’instància d’activitat, també heu de restaurar -lo quan es recrei l’activitat. Podeu fer -ho bé a onCreate (), o bé implementant la devolució de devolució de la devolució (), que es diu després de OneStart () després de la creació de l'activitat.
La majoria de les vegades, el lloc millor per restaurar l’estat d’activitat es troba a Oncreate (), per assegurar -se que la interfície d’usuari, inclòs l’estat, estigui disponible el més aviat possible. De vegades és convenient fer -ho a OnRestoreInstanceState () després de tota la inicialització o permetre que les subclasses decideixin si utilitzeu la vostra implementació per defecte.
- Al mètode onCreate (), després que les variables de vista s’inicialitzin amb FindViewById (), afegiu una prova per assegurar -vos que SavedInstanceState no és nul.
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
// Restore the state.
if (savedInstanceState != null) {
}
Quan es crea la vostra activitat, el sistema passa el paquet d'estat a onCreate () com a únic argument. La primera vegada que es diu onCreate () i la vostra aplicació comença, el paquet és nul: no hi ha cap estat existent la primera vegada que comenci la vostra aplicació. Les trucades posteriors a onCreate () tenen un paquet que es troba amb les dades que vau emmagatzemar a OnSaveInstanCeState ().
- Dins d'aquest xec, traieu la visibilitat actual (veritable o falsa) del paquet amb la clau "Respon_visible".
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
}
- Afegiu una prova a sota d'aquesta línia anterior per a la variable isvisible.
if (isVisible) {
}
Si hi ha una clau de resposta de resposta al paquet d’estat (i és cert que és cert), haureu de restaurar l’estat.
- Dins de la prova isvisible, feu que la capçalera sigui visible.
mReplyHeadTextView.setVisibility(View.VISIBLE);
- Obteniu el missatge de resposta de text del paquet amb la tecla "Respon_text" i configureu el text de resposta per mostrar aquesta cadena.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
- Feu que la resposta TextView també sigui visible:
mReplyTextView.setVisibility(View.VISIBLE);
- Executeu l'aplicació. Proveu de girar el dispositiu o l'emulador per assegurar -vos que el missatge de resposta (si n'hi ha) queda a la pantalla un cop recreada l'activitat.
Codi de solució de la tasca 2
Els fragments de codi següents mostren el codi de solució d'aquesta tasca.
Mainactivitat
Els fragments de codi següents mostren el codi afegit a MainActivity, però no a tota la classe.
El mètode OnSaveInstanceState ():
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// If the heading is visible, message needs to be saved.
// Otherwise we're still using default layout.
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
outState.putString("reply_text",
mReplyTextView.getText().toString());
}
}
El mètode onCreate ():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
// Restore the saved state.
// See onSaveInstanceState() for what gets saved.
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
// Show both the header and the message views. If isVisible is
// false or missing from the bundle, use the default layout.
if (isVisible) {
mReplyHeadTextView.setVisibility(View.VISIBLE);
mReplyTextView.setText(savedInstanceState
.getString("reply_text"));
mReplyTextView.setVisibility(View.VISIBLE);
}
}
}
El projecte complet:
Projecte Android Studio: Twoactivitieslifecycle
5. Codificació
Repte: creeu una aplicació de llista de compres senzill amb una activitat principal per a la llista que està construint l’usuari i una segona activitat per a una llista d’articles de compres comuns.
- L’activitat principal ha de contenir la llista per construir, que hauria d’estar formada per deu elements de text de text buits.
- Un botó Afegeix l’element a l’activitat principal llança una segona activitat que conté una llista d’articles de compres comuns (formatge, arròs, pomes, etc.). Utilitzeu elements del botó per mostrar els elements.
- L’elecció d’un element retorna l’usuari a l’activitat principal i actualitza una vista de text buida per incloure l’element escollit.
Utilitzeu una intenció per passar informació d’una activitat a una altra. Assegureu -vos que l'estat actual de la llista de compres es guardi quan l'usuari gira el dispositiu.
6. Resum
- El cicle de vida de l’activitat és un conjunt d’estats que una activitat migra, començant quan es crea per primera vegada i s’acaba quan el sistema Android recupera els recursos per a aquesta activitat.
- A mesura que l’usuari navega d’una activitat a una altra i dins i fora de la vostra aplicació, cada activitat es mou entre els estats del cicle de vida de l’activitat.
- Cada estat del cicle de vida de l’activitat té un mètode de devolució corresponent que podeu substituir a la vostra classe d’activitat.
- Els mètodes del cicle de vida són onCreate (), onStart (), onPause (), onRestart (), onResume (), onStop (), onDestroy ().
- Superar un mètode de devolució del cicle de vida permet afegir un comportament que es produeix quan la vostra activitat es transmet a aquest estat.
- Podeu afegir mètodes de substitució d'esquelet a les vostres classes a Android Studio amb codi> substitució.
- Els canvis de configuració del dispositiu com ara la rotació es tradueixen en la destrucció i recreada de l'activitat com si fos nou.
- Una part de l'estat d'activitat es conserva en un canvi de configuració, inclosos els valors actuals dels elements d'EditText. Per a la resta de dades, heu de desar explícitament aquestes dades.
- Desa l'estat de la instància d'activitat al mètode OnsaveInstanceState ().
- Les dades d’estat d’instància s’emmagatzemen com a parelles de clau/valor simples en un paquet. Utilitzeu els mètodes del paquet per posar les dades i tornar a treure les dades del paquet.
- Restaureu l'estat d'instància a onCreate (), que és la manera preferida, o onrestoreinstanceState (). Enrere
1. Benvingut
Aquesta pràctica CodeLab forma part de la unitat 1: iniciar -se en el curs Fonaments de desenvolupadors d'Android (versió 2). Obtindreu el màxim valor d’aquest curs si treballeu a través dels CodeLabs en seqüència:
- Per obtenir la llista completa de CodeLabs al curs, vegeu CodeLabs per als fonaments de desenvolupadors d'Android (V2).
- Per obtenir més informació sobre el curs, inclosos els enllaços a tots els capítols de concepte, aplicacions i diapositives, vegeu Fonaments de desenvolupadors d'Android (versió 2).
Introducció
En aquesta pràctica, obtindreu més informació sobre el cicle de vida de l’activitat. El cicle de vida és el conjunt d’estats que pot ser una activitat durant tota la seva vida, des de quan es crea fins a la destrucció i el sistema recupera els seus recursos. A mesura que l’usuari navega entre activitats de la vostra aplicació (així com dins i fora de la vostra aplicació), la transició d’activitats entre diferents estats en els seus cicles de vida.
Cada etapa del cicle de vida d’una activitat té un mètode de devolució corresponent: onCreate (), onStart (), onPause (), etc. Quan una activitat canvia d’estat, s’invoca el mètode de devolució associat. Ja heu vist un d'aquests mètodes: onCreate (). En substituir qualsevol dels mètodes de devolució del cicle de vida de les vostres classes d’activitat, podeu canviar el comportament predeterminat de l’activitat en resposta a les accions d’usuari o sistema.
L’estat d’activitat també pot canviar com a resposta als canvis de configuració del dispositiu, per exemple quan l’usuari gira el dispositiu des del retrat al paisatge. Quan es produeixen aquests canvis de configuració, l’activitat es destrueix i es recreà en el seu estat predeterminat i l’usuari pot perdre informació que han introduït a l’activitat. Per evitar confondre els usuaris, és important que desenvolupeu la vostra aplicació per evitar pèrdues inesperades de dades. Més endavant en aquesta pràctica, experimenteu amb canvis de configuració i apreneu a preservar l’estat d’una activitat en resposta als canvis de configuració del dispositiu i altres esdeveniments del cicle de vida de l’activitat.
En aquesta pràctica, afegiu declaracions de registre a l’aplicació Twoactivities i observeu els canvis de cicle de vida de l’activitat a mesura que utilitzeu l’aplicació. A continuació, comenceu a treballar amb aquests canvis i a explorar com gestionar l’entrada dels usuaris en aquestes condicions.
Requisits previs
Hauríeu de ser capaços de:
- Creeu i executeu un projecte d'aplicacions a Android Studio .
- Afegiu declaracions de registre a la vostra aplicació i visualitzeu aquests registres al panell de registre.
- Comprendre i treballar amb una activitat i una intenció i estar còmode interactuant amb ells.
El que aprendràs
- Com funciona el cicle de vida de l’activitat.
- Quan s’inicia una activitat, s’atura, s’atura i es destrueix.
- Sobre els mètodes de trucada de cicle de vida associats als canvis d’activitat.
- L’efecte de les accions (com ara els canvis de configuració) que poden donar lloc a esdeveniments del cicle de vida de l’activitat.
- Com conservar l'estat de l'activitat entre els esdeveniments del cicle de vida.
Què faràs
- Afegiu codi a l’aplicació Twoactivities de la pràctica anterior per implementar les diverses devolucions de cicle de vida de l’activitat per incloure les declaracions de registre.
- Observeu l'estat canvia a mesura que s'executa l'aplicació i mentre interactueu amb cada activitat de la vostra aplicació.
- Modifiqueu la vostra aplicació per conservar l’estat d’instància d’una activitat que es recreà inesperadament en resposta al comportament de l’usuari o al canvi de configuració del dispositiu.
2. Visió general de l'aplicació
En aquesta pràctica s’afegeix a l’aplicació Twoactivities . L’aplicació es veu i es comporta aproximadament el mateix que ho va fer a l’últim CodeLab. Conté dues implementacions d’activitats i proporciona a l’usuari la possibilitat d’enviar entre elles. Els canvis que feu a l'aplicació en aquesta pràctica no afectaran el seu comportament visible dels usuaris.
3. 3. Tasca 1: Afegiu les trucades del cicle de vida a dues activitats
En aquesta tasca implementareu tots els mètodes de devolució del cicle de vida de l’activitat per imprimir missatges a logCAT quan s’invoca aquests mètodes. Aquests missatges de registre us permetran veure quan el cicle de vida de l’activitat canvia d’estat i com afecten els canvis d’estat del cicle de vida a mesura que s’executa.
1.1 (opcional) Copieu el projecte de dues activitats
Per a les tasques d'aquesta pràctica, modificareu el projecte de dues activitats existent que heu creat en l'últim pràctic. Si preferiu mantenir intacte el projecte de dues activitats anteriors, seguiu els passos a l’apèndix: Utilitats per fer una còpia del projecte.
1.2 Implementar les trucades a MainActivity
- Obriu el projecte de dues activitats a Android Studio i obriu MainActivity al Projecte> Android Pane.
- Al mètode onCreate (), afegiu les afirmacions de registre següents:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
- Afegiu una substitució per a la devolució de devolució (), amb una declaració al registre d'aquest esdeveniment:
@Override
public void onStart(){
super.onStart();
Log.d(LOG_TAG, "onStart");
}
Per a una drecera, seleccioneu Codi> Mètodes de substitució a Android Studio. Apareix un diàleg amb tots els mètodes possibles que podeu substituir a la vostra classe. L’elecció d’un o més mètodes de devolució de la llista insereix una plantilla completa per a aquests mètodes, inclosa la trucada necessària a la superclasse.
- Utilitzeu el mètode onStart () com a plantilla per implementar les devolució de la vida onPause (), OnRestart (), OnResume (), OnStop () i OnDestroy ()
Tots els mètodes de devolució tenen les mateixes signatures (excepte el nom). Si copieu i enganxeu OnStart () per crear aquests altres mètodes de trucada, no us oblideu d’actualitzar el contingut per trucar al mètode adequat a la superclasse i registrar el mètode correcte.
- Executeu la vostra aplicació.
- Feu clic a la pestanya Logcat a la part inferior d'Android Studio per mostrar el panell Logcat. Hauríeu de veure tres missatges de registre que mostren els tres estats del cicle de vida que l’activitat ha passat a l’hora de començar:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume
1.3 Implementar les trucades del cicle de vida a SeconActivity
Ara que heu implementat els mètodes de devolució del cicle de vida per a MainActivity, feu el mateix per a SeconActivity.
- Obriu la segona activitat.
- A la part superior de la classe, afegiu una constant per a la variable log_tag:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
- Afegiu els cicles de vida i les declaracions de registre a la segona activitat. (Podeu copiar i enganxar els mètodes de devolució de MainActivity.)
- Afegiu una instrucció de registre al mètode returnReply () just abans del mètode Final ():
Log.d(LOG_TAG, "End SecondActivity");
1.4 Observeu el registre a mesura que s'executa l'aplicació **
- Executeu la vostra aplicació.
- Feu clic a la pestanya Logcat a la part inferior d'Android Studio per mostrar el panell Logcat.
- Introduïu l'activitat al quadre de cerca. El Logcat d'Android pot ser molt llarg i desordenat. Com que la variable log_tag de cada classe conté les paraules MainActivity o SeconActivity, aquesta paraula clau us permet filtrar el registre només per a les coses que us interessa.
Experimenteu mitjançant la vostra aplicació i tingueu en compte que els esdeveniments del cicle de vida que es produeixen en resposta a diferents accions. En particular, proveu aquestes coses:
- Utilitzeu l'aplicació normalment (envieu un missatge, responeu amb un altre missatge).
- Utilitzeu el botó enrere per tornar de la segona activitat a la principal activitat.
- Utilitzeu la fletxa amunt de la barra d'aplicacions per tornar de la segona activitat a la principal activitat.
- Gireu el dispositiu tant a la principal com a la segona activitat en diferents moments de la vostra aplicació i observeu què passa a * el registre i a la pantalla.
- Premeu el botó de visió general (el botó quadrat a la dreta de casa) i tanqueu l'aplicació (toqueu la X).
- Torneu a la pantalla d'inici i reinicieu l'aplicació.
Consell: si executeu la vostra aplicació en un emulador, podeu simular la rotació amb Control+F11 o Control+Function+F11.
Codi de solució de la tasca 1
Els fragments de codi següents mostren el codi de solució per a la primera tasca.
Mainactivitat
Els fragments de codi següents mostren el codi afegit a MainActivity, però no a tota la classe.
El mètode onCreate ():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Log the start of the onCreate() method.
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
}
Els altres mètodes del cicle de vida:
@Override
protected void onStart() {
super.onStart();
Log.d(LOG_TAG, "onStart");
}
@Override
protected void onPause() {
super.onPause();
Log.d(LOG_TAG, "onPause");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(LOG_TAG, "onRestart");
}
@Override
protected void onResume() {
super.onResume();
Log.d(LOG_TAG, "onResume");
}
@Override
protected void onStop() {
super.onStop();
Log.d(LOG_TAG, "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(LOG_TAG, "onDestroy");
}
Secondactivitat
Els fragments de codi següents mostren el codi afegit a SeconActivity, però no a tota la classe.
A la part superior de la classe de SeconActivity:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
El mètode returnReply ():
public void returnReply(View view) {
String reply = mReply.getText().toString();
Intent replyIntent = new Intent();
replyIntent.putExtra(EXTRA_REPLY, reply);
setResult(RESULT_OK, replyIntent);
Log.d(LOG_TAG, "End SecondActivity");
finish();
}
Els altres mètodes del cicle de vida:
Igual que per a MainActivity, més amunt.
4. 4. Tasca 2: Desar i restaurar l’estat d’instància d’activitat
Segons els recursos del sistema i el comportament dels usuaris, cada activitat de la vostra aplicació pot ser destruïda i reconstruïda amb més freqüència del que podríeu pensar.
És possible que hagueu notat aquest comportament a l’última secció quan heu girat el dispositiu o l’emulador. Rotar el dispositiu és un exemple de canvi de configuració del dispositiu. Tot i que la rotació és la més comuna, tots els canvis de configuració donen lloc a que l’activitat actual sigui destruïda i recreada com si fos nova. Si no teniu en compte aquest comportament al vostre codi, quan es produeix un canvi de configuració, el disseny de l’activitat pot tornar a la seva aparença predeterminada i valors inicials, i els usuaris poden perdre el seu lloc, les seves dades o l’estat del seu progrés la vostra aplicació.
L’estat de cada activitat s’emmagatzema com a conjunt de parells de claus/valor en un objecte de paquet anomenat Estat d’instància d’activitat. El sistema estalvia informació d’estat predeterminat al paquet d’estat d’instància just abans de l’aturada de l’activitat i passa aquest paquet a la nova instància d’activitat per restaurar.
Per evitar perdre les dades en una activitat quan es destrueix i es recrea inesperadament, heu d’implementar el mètode OnSaveInstanceState (). El sistema anomena aquest mètode a la vostra activitat (entre onPause () i OnStop ()) quan hi ha la possibilitat que l'activitat es pugui destruir i recrear.
Les dades que guardeu en l’estat d’instància són específiques només per a aquesta instància d’aquesta activitat específica durant la sessió d’aplicació actual. Quan atureu i reinicieu una nova sessió d'aplicacions, l'estat de la instància d'activitat es perd i l'activitat torna a la seva aparença per defecte. Si necessiteu desar les dades de l’usuari entre les sessions d’aplicacions, utilitzeu preferències compartides o una base de dades. Apreneu sobre tots dos en una pràctica posterior.
2.1 Desa l'estat de la instància d'activitat amb OnSaveInstanceState ()
És possible que hagueu notat que girar el dispositiu no afecta en absolut l’estat de la segona activitat. Això es deu al fet que la segona disposició i estat de l’activitat es generen a partir del disseny i la intenció que l’activessin. Tot i que l’activitat es recreà, la intenció encara hi és i les dades en aquesta intenció encara s’utilitzen cada vegada que s’anomena el mètode oncreate () de la segona activitat.
A més, podeu notar que en cada activitat, qualsevol text que heu escrit a Missatge o Respon alements EditText es conserva fins i tot quan es gira el dispositiu. Això es deu al fet que la informació estatal d’alguns dels elements de vista del disseny es desarà automàticament en els canvis de configuració i el valor actual d’un editText és un d’aquests casos.
Per tant, l'únic estat d'activitat que us interessa són els elements de TextView per a la capçalera de resposta i el text de resposta a l'activitat principal. Els dos elements de TextView són invisibles per defecte; Només apareixen un cop envieu un missatge a l’activitat principal de la segona activitat.
En aquesta tasca, afegiu codi per preservar l'estat de la instància d'aquests dos elements de TextView mitjançant OnsaveInstanCeState ().
- Obert MainActivitat.
- Afegiu aquesta implementació d'esquelet de OnSaveInstanceState () a l'activitat o utilitzeu el codi> Substituir mètodes per inserir una substitució d'esquelet.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
- Comproveu si actualment la capçalera és visible i, si és així, poseu aquest estat de visibilitat al paquet d’estat amb el mètode PutBoolean () i la clau "Respon_visible".
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
}
Recordeu que l’encapçalament de la resposta i el text estan marcats invisibles fins que hi hagi una resposta de la segona activitat. Si la capçalera és visible, hi ha dades de resposta que cal desar. Tingueu en compte que només ens interessa aquest estat de visibilitat: el text real de la capçalera no s'ha de desar, perquè aquest text no canvia mai.
- Dins d'aquesta mateixa comprovació, afegiu el text de resposta al paquet.
outState.putString("reply_text",mReplyTextView.getText().toString());
Si la capçalera és visible, podeu suposar que el missatge de resposta en si també és visible. No cal provar ni guardar l'estat de visibilitat actual del missatge de resposta. Només el text real del missatge entra al paquet d'estat amb la clau "Respon_text".
Estalvieu l’estat només d’aquells elements de vista que poden canviar després de la creació de l’activitat. Els altres elements de vista de la vostra aplicació (el botó EditText, el botó) es poden recrear des de la disposició predeterminada en qualsevol moment.
Tingueu en compte que el sistema estalviarà l'estat d'alguns elements de vista, com ara el contingut de l'EditText.
2.2 Restaureu l'estat d'instància d'activitat a onCreate ()
Un cop hagueu guardat l’estat d’instància d’activitat, també heu de restaurar -lo quan es recrei l’activitat. Podeu fer -ho bé a onCreate (), o bé implementant la devolució de devolució de la devolució (), que es diu després de OneStart () després de la creació de l'activitat.
La majoria de les vegades, el lloc millor per restaurar l’estat d’activitat es troba a Oncreate (), per assegurar -se que la interfície d’usuari, inclòs l’estat, estigui disponible el més aviat possible. De vegades és convenient fer -ho a onRestoreInstanceState () després de tota la inicialització o permetre que les subclasses decideixin si utilitzeu la vostra implementació predeterminada.
- Al mètode onCreate (), després que les variables de vista s’inicialitzin amb FindViewById (), afegiu una prova per assegurar -vos que SavedInstanceState no és nul.
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
// Restore the state.
if (savedInstanceState != null) {
}
Quan es crea la vostra activitat, el sistema passa el paquet d'estat a onCreate () com a únic argument. The first time onCreate() is called and your app starts, the Bundle is null—there's no existing state the first time your app starts. Subsequent calls to onCreate() have a bundle populated with the data you stored in onSaveInstanceState().
- Inside that check, get the current visibility (true or false) out of the Bundle with the key "reply_visible".
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
}
- Add a test below that previous line for the isVisible variable.
if (isVisible) {
}
If there's a reply_visible key in the state Bundle (and isVisible is therefore true), you will need to restore the state.
- Inside the isVisible test, make the header visible.
mReplyHeadTextView.setVisibility(View.VISIBLE);
- Get the text reply message from the Bundle with the key "reply_text", and set the reply TextView to show that string.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
- Make the reply TextView visible as well:
mReplyTextView.setVisibility(View.VISIBLE);
- Run the app. Try rotating the device or the emulator to ensure that the reply message (if there is one) remains on the screen after the Activity is recreated.
Task 2 solution code
The following code snippets show the solution code for this task.
MainActivity
The following code snippets show the added code in MainActivity, but not the entire class.
The onSaveInstanceState() method:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// If the heading is visible, message needs to be saved.
// Otherwise we're still using default layout.
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
outState.putString("reply_text",
mReplyTextView.getText().toString());
}
}
The onCreate() method:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
// Initialize all the view variables.
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
// Restore the saved state.
// See onSaveInstanceState() for what gets saved.
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
// Show both the header and the message views. If isVisible is
// false or missing from the bundle, use the default layout.
if (isVisible) {
mReplyHeadTextView.setVisibility(View.VISIBLE);
mReplyTextView.setText(savedInstanceState
.getString("reply_text"));
mReplyTextView.setVisibility(View.VISIBLE);
}
}
}
The complete project:
Android Studio Project: TwoActivitiesLifecycle
5. Coding
Challenge: Create a simple shopping-list app with a main activity for the list the user is building, and a second activity for a list of common shopping items.
- The main activity should contain the list to build, which should be made up of ten empty TextView elements.
- An Add Item button on the main activity launches a second activity that contains a list of common shopping items (Cheese, Rice, Apples, and so on). Use Button elements to display the items.
- Choosing an item returns the user to the main activity, and updates an empty TextView to include the chosen item.
Use an Intent to pass information from one Activity to another. Make sure that the current state of the shopping list is saved when the user rotates the device.
6. Summary
- The Activity lifecycle is a set of states an Activity migrates through, beginning when it is first created and ending when the Android system reclaims the resources for that Activity.
- As the user navigates from one Activity to another, and inside and outside of your app, each Activity moves between states in the Activity lifecycle.
- Each state in the Activity lifecycle has a corresponding callback method you can override in your Activity class.
- The lifecycle methods are onCreate(), onStart(), onPause(), onRestart(), onResume(), onStop(), onDestroy().
- Overriding a lifecycle callback method allows you to add behavior that occurs when your Activity transitions into that state.
- You can add skeleton override methods to your classes in Android Studio with Code > Override.
- Device configuration changes such as rotation results in the Activity being destroyed and recreated as if it were new.
- A portion of the Activity state is preserved on a configuration change, including the current values of EditText elements. For all other data, you must explicitly save that data yourself.
- Save Activity instance state in the onSaveInstanceState() method.
- Instance state data is stored as simple key/value pairs in a Bundle. Use the Bundle methods to put data into and get data back out of the Bundle.
- Restore the instance state in onCreate(), which is the preferred way, or onRestoreInstanceState(). Enrere