1. Velkommen
Denne praktiske kodelabben er en del av Unit 1: Kom i gang med Android Developer Fundamentals (versjon 2)-kurset. Du vil få mest mulig ut av dette kurset hvis du arbeider gjennom kodelabbene i rekkefølge:
- For den fullstendige listen over kodelaber i kurset, se Codelabs for Android Developer Fundamentals (V2).
- For detaljer om kurset, inkludert lenker til alle konseptkapitlene, appene og lysbildene, se Android Developer Fundamentals (versjon 2).
Introduksjon
I denne øvelsen lærer du mer om aktivitetens livssyklus. Livssyklusen er settet med tilstander en aktivitet kan være i gjennom hele levetiden, fra den er opprettet til den blir ødelagt og systemet tar tilbake ressursene sine. Når en bruker navigerer mellom aktiviteter i appen din (så vel som inn og ut av appen), går aktiviteter over mellom ulike tilstander i livssyklusen.
Hvert trinn i en aktivitets livssyklus har en tilsvarende tilbakeringingsmetode: onCreate(), onStart(), onPause() og så videre. Når en aktivitet endrer tilstand, aktiveres den tilknyttede tilbakeringingsmetoden. Du har allerede sett en av disse metodene: onCreate(). Ved å overstyre noen av tilbakeringingsmetodene for livssyklusen i aktivitetsklassene dine, kan du endre aktivitetens standardoppførsel som svar på bruker- eller systemhandlinger.
Aktivitetstilstanden kan også endres som svar på endringer i enhetskonfigurasjonen, for eksempel når brukeren roterer enheten fra stående til liggende. Når disse konfigurasjonsendringene skjer, blir aktiviteten ødelagt og gjenskapt i standardtilstanden, og brukeren kan miste informasjon som de har lagt inn i aktiviteten. For å unngå å forvirre brukerne dine, er det viktig at du utvikler appen din for å forhindre uventet tap av data. Senere i dette praktiske eksperimentet eksperimenterer du med konfigurasjonsendringer og lærer hvordan du kan bevare en aktivitets tilstand som svar på enhetskonfigurasjonsendringer og andre aktivitetslivssyklushendelser.
I denne praktiske artikkelen legger du til loggsetninger til TwoActivities-appen og observerer endringer i aktivitetslivssyklusen mens du bruker appen. Deretter begynner du å jobbe med disse endringene og utforske hvordan du håndterer brukerinnspill under disse forholdene.
Forutsetninger
Du bør kunne:
- Opprett og kjør et appprosjekt i Android Studio .
- Legg til loggsetninger i appen din og se loggene i Logcat-ruten.
- Forstå og arbeid med en aktivitet og en intensjon, og vær komfortabel med å samhandle med dem.
Hva du vil lære
- Hvordan Aktivitets livssyklus fungerer.
- Når en aktivitet starter, stopper, stopper og blir ødelagt.
- Om tilbakeringingsmetodene for livssyklusen knyttet til aktivitetsendringer.
- Effekten av handlinger (som konfigurasjonsendringer) som kan resultere i aktivitetslivssyklushendelser.
- Hvordan beholde aktivitetsstatus på tvers av livssyklushendelser.
Hva du skal gjøre
- Legg til kode i TwoActivities -appen fra forrige praktiske for å implementere de ulike aktivitetslivssyklustilbakekallingene for å inkludere loggingssetninger.
- Observer tilstandsendringene mens appen din kjører og når du samhandler med hver aktivitet i appen din.
- Endre appen din for å beholde forekomsttilstanden til en aktivitet som uventet gjenskapes som svar på brukeratferd eller konfigurasjonsendring på enheten.
2. App-oversikt
I dette praktiske legger du til TwoActivities -appen. Appen ser ut og oppfører seg omtrent på samme måte som den gjorde i forrige codelab. Den inneholder to Activity-implementeringer og gir brukeren muligheten til å sende mellom dem. Endringene du gjør i appen i denne praktiske appen vil ikke påvirke den synlige brukeratferden.
3. 3. Oppgave 1: Legg til livssyklus tilbakeringinger til TwoActivities
I denne oppgaven skal du implementere alle tilbakeringingsmetodene for aktivitetslivssyklusen for å skrive ut meldinger til logcat når disse metodene påkalles. Disse loggmeldingene lar deg se når aktivitetens livssyklus endrer tilstand, og hvordan disse livssyklustilstandsendringene påvirker appen din mens den kjører.
1.1 (Valgfritt) Kopier TwoActivities-prosjektet
For oppgavene i denne praksisen, vil du modifisere det eksisterende TwoActivities -prosjektet du bygde i den siste praktiske. Hvis du foretrekker å beholde det forrige TwoActivities-prosjektet intakt, følg trinnene i Vedlegg: Verktøy for å lage en kopi av prosjektet.
1.2 Implementer tilbakeringinger i MainActivity
- Åpne TwoActivities-prosjektet i Android Studio, og åpne MainActivity i Prosjekt > Android-panelet.
- I onCreate()-metoden legger du til følgende loggsetninger:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
- Legg til en overstyring for onStart()-tilbakekallingen, med en uttalelse til loggen for den hendelsen:
@Override
public void onStart(){
super.onStart();
Log.d(LOG_TAG, "onStart");
}
For en snarvei, velg Kode > Overstyr metoder i Android Studio. En dialogboks vises med alle de mulige metodene du kan overstyre i klassen din. Ved å velge en eller flere tilbakeringingsmetoder fra listen setter du inn en komplett mal for disse metodene, inkludert det nødvendige kallet til superklassen.
- Bruk onStart()-metoden som en mal for å implementere onPause(), onRestart(), onResume(), onStop() og onDestroy() livssyklustilbakekallinger
Alle tilbakeringingsmetodene har samme signaturer (bortsett fra navnet). Hvis du kopierer og limer inn onStart() for å lage disse andre tilbakeringingsmetodene, ikke glem å oppdatere innholdet for å kalle den riktige metoden i superklassen, og for å logge den riktige metoden.
- Kjør appen din.
- Klikk på Logcat-fanen nederst i Android Studio for å vise Logcat-ruten. Du skal se tre loggmeldinger som viser de tre livssyklustilstandene aktiviteten har gått gjennom da den startet:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume
1.3 Implementer tilbakeringing av livssyklus i SecondActivity
Nå som du har implementert metodene for tilbakeringing av livssyklusen for MainActivity, gjør du det samme for SecondActivity.
- Åpne SecondActivity.
- Øverst i klassen legger du til en konstant for LOG_TAG-variabelen:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
- Legg til livssyklus-tilbakringing og loggsetninger til den andre aktiviteten. (Du kan kopiere og lime inn tilbakeringingsmetodene fra MainActivity.)
- Legg til en loggsetning til returnReply()-metoden like før finish()-metoden:
Log.d(LOG_TAG, "End SecondActivity");
1.4 Observer loggen mens appen kjører**
- Kjør appen din.
- Klikk på Logcat-fanen nederst i Android Studio for å vise Logcat-ruten.
- Skriv inn aktivitet i søkefeltet. Android logcat kan være veldig lang og rotete. Fordi LOG_TAG-variabelen i hver klasse inneholder enten ordene MainActivity eller SecondActivity, lar dette søkeordet deg filtrere loggen for bare de tingene du er interessert i.
Eksperimenter med appen din og merk at livssyklushendelsene som oppstår som svar på forskjellige handlinger. Prøv spesielt disse tingene:
- Bruk appen normalt (send en melding, svar med en annen melding).
- Bruk Tilbake-knappen for å gå tilbake fra den andre aktiviteten til hovedaktiviteten.
- Bruk opp-pilen i applinjen for å gå tilbake fra den andre aktiviteten til hovedaktiviteten.
- Roter enheten på både hovedaktiviteten og den andre aktiviteten til forskjellige tider i appen din og observer hva som skjer i * loggen og på skjermen.
- Trykk på oversiktsknappen (den firkantede knappen til høyre for Hjem) og lukk appen (trykk på X).
- Gå tilbake til startskjermen og start appen på nytt.
TIPS: Hvis du kjører appen din i en emulator, kan du simulere rotasjon med Control+F11 eller Control+Function+F11.
Oppgave 1 løsningskode
Følgende kodebiter viser løsningskoden for den første oppgaven.
Hovedaktivitet
Følgende kodebiter viser den tillagte koden i MainActivity, men ikke hele klassen.
onCreate()-metoden:
@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);
}
De andre livssyklusmetodene:
@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");
}
SecondActivity
Følgende kodebiter viser den tillagte koden i SecondActivity, men ikke hele klassen.
På toppen av SecondActivity-klassen:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
ReturnReply()-metoden:
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();
}
De andre livssyklusmetodene:
Samme som for MainActivity, ovenfor.
4. 4. Oppgave 2: Lagre og gjenopprett aktivitetsforekomsttilstanden
Avhengig av systemressurser og brukeratferd, kan hver aktivitet i appen din bli ødelagt og rekonstruert mye oftere enn du kanskje tror.
Du har kanskje lagt merke til denne oppførselen i den siste delen da du roterte enheten eller emulatoren. Rotering av enheten er ett eksempel på endring av enhetskonfigurasjon. Selv om rotasjon er den vanligste, resulterer alle konfigurasjonsendringer i at den nåværende aktiviteten blir ødelagt og gjenskapt som om den var ny. Hvis du ikke tar hensyn til denne oppførselen i koden din, når det skjer en konfigurasjonsendring, kan aktivitetsoppsettet ditt gå tilbake til standardutseende og startverdier, og brukerne dine kan miste plassen sin, dataene eller statusen til fremdriften i appen din.
Tilstanden til hver aktivitet lagres som et sett med nøkkel/verdi-par i et Bundle-objekt kalt Aktivitetsforekomsttilstanden. Systemet lagrer standardtilstandsinformasjon til instanstilstandspakke rett før aktiviteten stoppes, og sender denne pakken til den nye aktivitetsforekomsten for å gjenopprette.
For å unngå å miste data i en aktivitet når den uventet blir ødelagt og gjenskapt, må du implementere onSaveInstanceState()-metoden. Systemet kaller denne metoden på aktiviteten din (mellom onPause() og onStop()) når det er en mulighet for at aktiviteten kan bli ødelagt og gjenskapt.
Dataene du lagrer i forekomsttilstanden, er spesifikke for bare denne forekomsten av denne spesifikke aktiviteten under gjeldende appøkt. Når du stopper og starter en ny appøkt på nytt, går aktivitetsforekomsttilstanden tapt og aktiviteten går tilbake til standardutseendet. Hvis du trenger å lagre brukerdata mellom appøkter, bruk delte preferanser eller en database. Du lærer om begge disse i en senere praksis.
2.1 Lagre aktivitetsforekomsttilstanden med onSaveInstanceState()
Du har kanskje lagt merke til at rotering av enheten ikke påvirker tilstanden til den andre aktiviteten i det hele tatt. Dette er fordi det andre aktivitetsoppsettet og tilstanden genereres fra oppsettet og intensjonen som aktiverte den. Selv om aktiviteten gjenskapes, er intensjonen fortsatt der, og dataene i den hensikten brukes fortsatt hver gang onCreate()-metoden i den andre aktiviteten kalles.
I tillegg kan du legge merke til at i hver aktivitet beholdes all tekst du skrev inn i meldinger eller svar EditText-elementer selv når enheten roteres. Dette er fordi tilstandsinformasjonen til noen av View-elementene i layouten din lagres automatisk på tvers av konfigurasjonsendringer, og den gjeldende verdien av en EditText er et av disse tilfellene.
Så den eneste aktivitetstilstanden du er interessert i er TextView-elementene for svaroverskriften og svarteksten i hovedaktiviteten. Begge TextView-elementene er usynlige som standard; de vises bare når du sender en melding tilbake til hovedaktiviteten fra den andre aktiviteten.
I denne oppgaven legger du til kode for å bevare forekomsttilstanden til disse to TextView-elementene ved å bruke onSaveInstanceState().
- Åpne MainActivity.
- Legg til denne skjelettimplementeringen av onSaveInstanceState() til aktiviteten, eller bruk Kode > Overstyringsmetoder for å sette inn en skjelettoverstyring.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
- Sjekk for å se om overskriften er synlig for øyeblikket, og i så fall legg den synlighetstilstanden inn i tilstandspakken med putBoolean()-metoden og nøkkelen "reply_visible".
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
}
Husk at svaroverskriften og teksten er merket som usynlig inntil det kommer et svar fra den andre aktiviteten. Hvis overskriften er synlig, er det svardata som må lagres. Merk at vi bare er interessert i den synlighetstilstanden - selve teksten i overskriften trenger ikke å lagres, fordi den teksten aldri endres.
- I den samme sjekken legger du til svarteksten i pakken.
outState.putString("reply_text",mReplyTextView.getText().toString());
Hvis overskriften er synlig kan du anta at selve svarmeldingen også er synlig. Du trenger ikke å teste for eller lagre gjeldende synlighetsstatus for svarmeldingen. Bare selve teksten i meldingen går inn i tilstandspakken med nøkkelen "reply_text".
Du lagrer kun tilstanden til de View-elementene som kan endres etter at aktiviteten er opprettet. De andre View-elementene i appen din (Redigeringsteksten, knappen) kan gjenskapes fra standardoppsettet når som helst.
Merk at systemet vil lagre tilstanden til enkelte View-elementer, for eksempel innholdet i EditText.
2.2 Gjenopprett aktivitetsforekomsttilstanden i onCreate()
Når du har lagret aktivitetsforekomsttilstanden, må du også gjenopprette den når aktiviteten gjenopprettes. Du kan gjøre dette enten i onCreate(), eller ved å implementere tilbakekallingen onRestoreInstanceState(), som kalles opp etter onStart() etter at aktiviteten er opprettet.
Mesteparten av tiden er det bedre stedet å gjenopprette aktivitetstilstanden i onCreate(), for å sikre at brukergrensesnittet, inkludert tilstanden, er tilgjengelig så snart som mulig. Noen ganger er det praktisk å gjøre det i onRestoreInstanceState() etter at all initialiseringen er utført, eller å la underklasser bestemme om de skal bruke standardimplementeringen.
- I onCreate()-metoden, etter at View-variablene er initialisert med findViewById(), legger du til en test for å sikre at savedInstanceState ikke er null.
// 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) {
}
Når aktiviteten din er opprettet, sender systemet tilstandspakken til onCreate() som eneste argument. Første gang onCreate() kalles og appen din starter, er pakken null – det er ingen eksisterende tilstand første gang appen din starter. Påfølgende kall til onCreate() har en bunt fylt med dataene du har lagret i onSaveInstanceState().
- Inne i den sjekken, få gjeldende synlighet (sant eller usant) ut av pakken med nøkkelen "reply_visible".
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
}
- Legg til en test under den forrige linjen for variabelen isVisible.
if (isVisible) {
}
Hvis det er en reply_visible-nøkkel i tilstandspakken (og isVisible er derfor sant), må du gjenopprette tilstanden.
- Gjør overskriften synlig i isVisible-testen.
mReplyHeadTextView.setVisibility(View.VISIBLE);
- Få tekstsvarmeldingen fra pakken med nøkkelen "reply_text", og still inn svaret TextView til å vise den strengen.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
- Gjør også svaret TextView synlig:
mReplyTextView.setVisibility(View.VISIBLE);
- Kjør appen. Prøv å rotere enheten eller emulatoren for å sikre at svarmeldingen (hvis det er en) forblir på skjermen etter at aktiviteten er gjenskapt.
Oppgave 2 løsningskode
Følgende kodebiter viser løsningskoden for denne oppgaven.
Hovedaktivitet
Følgende kodebiter viser den tillagte koden i MainActivity, men ikke hele klassen.
OnSaveInstanceState()-metoden:
@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());
}
}
onCreate()-metoden:
@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);
}
}
}
Det komplette prosjektet:
Android Studio Project: TwoActivitiesLifecycle
5. Koding
Utfordring: Lag en enkel handleliste-app med en hovedaktivitet for listen brukeren bygger, og en andre aktivitet for en liste over vanlige handlevarer.
- Hovedaktiviteten bør inneholde listen som skal bygges, som skal bestå av ti tomme TextView-elementer.
- En Add Item-knapp på hovedaktiviteten starter en annen aktivitet som inneholder en liste over vanlige handlevarer (ost, ris, epler og så videre). Bruk knappeelementer for å vise elementene.
- Ved å velge et element returnerer brukeren til hovedaktiviteten, og oppdaterer en tom tekstvisning for å inkludere det valgte elementet.
Bruk en intensjon for å overføre informasjon fra en aktivitet til en annen. Sørg for at gjeldende status for handlelisten er lagret når brukeren roterer enheten.
6. Sammendrag
- Aktivitetslivssyklusen er et sett med tilstander en aktivitet migrerer gjennom, som begynner når den først opprettes og slutter når Android-systemet tar tilbake ressursene for den aktiviteten.
- Når brukeren navigerer fra en aktivitet til en annen, og i og utenfor appen din, flytter hver aktivitet mellom tilstander i aktivitetslivssyklusen.
- Hver tilstand i aktivitetslivssyklusen har en tilsvarende tilbakeringingsmetode du kan overstyre i aktivitetsklassen din.
- Livssyklusmetodene er onCreate(), onStart(), onPause(), onRestart(), onResume(), onStop(), onDestroy().
- Ved å overstyre en tilbakeringingsmetode for livssyklus kan du legge til atferd som oppstår når aktiviteten din går over til den tilstanden.
- Du kan legge til skjelettoverstyringsmetoder i klassene dine i Android Studio med Kode > Overstyr.
- Endringer i enhetskonfigurasjonen som rotasjon resulterer i at aktiviteten blir ødelagt og gjenskapt som om den var ny.
- En del av aktivitetstilstanden blir bevart ved en konfigurasjonsendring, inkludert gjeldende verdier til EditText-elementer. For alle andre data må du eksplisitt lagre disse dataene selv.
- Lagre aktivitetsforekomsttilstand i onSaveInstanceState()-metoden.
- Forekomsttilstandsdata lagres som enkle nøkkel/verdi-par i en pakke. Bruk Bundle-metodene for å legge data inn i og få data tilbake ut av Bundle.
- Gjenopprett forekomsttilstanden i onCreate(), som er den foretrukne måten, eller onRestoreInstanceState(). Tilbake
1. Velkommen
Denne praktiske kodelabben er en del av Unit 1: Kom i gang med Android Developer Fundamentals (versjon 2)-kurset. Du vil få mest mulig ut av dette kurset hvis du arbeider gjennom kodelabbene i rekkefølge:
- For den fullstendige listen over kodelaber i kurset, se Codelabs for Android Developer Fundamentals (V2).
- For detaljer om kurset, inkludert lenker til alle konseptkapitlene, appene og lysbildene, se Android Developer Fundamentals (versjon 2).
Introduksjon
I denne øvelsen lærer du mer om aktivitetens livssyklus. Livssyklusen er settet med tilstander en aktivitet kan være i gjennom hele levetiden, fra den er opprettet til den blir ødelagt og systemet tar tilbake ressursene sine. Når en bruker navigerer mellom aktiviteter i appen din (så vel som inn og ut av appen), går aktiviteter over mellom ulike tilstander i livssyklusen.
Hvert trinn i en aktivitets livssyklus har en tilsvarende tilbakeringingsmetode: onCreate(), onStart(), onPause() og så videre. Når en aktivitet endrer tilstand, aktiveres den tilknyttede tilbakeringingsmetoden. Du har allerede sett en av disse metodene: onCreate(). Ved å overstyre noen av tilbakeringingsmetodene for livssyklusen i aktivitetsklassene dine, kan du endre aktivitetens standardoppførsel som svar på bruker- eller systemhandlinger.
Aktivitetstilstanden kan også endres som svar på endringer i enhetskonfigurasjonen, for eksempel når brukeren roterer enheten fra stående til liggende. Når disse konfigurasjonsendringene skjer, blir aktiviteten ødelagt og gjenskapt i standardtilstanden, og brukeren kan miste informasjon som de har lagt inn i aktiviteten. For å unngå å forvirre brukerne dine, er det viktig at du utvikler appen din for å forhindre uventet tap av data. Senere i dette praktiske eksperimentet eksperimenterer du med konfigurasjonsendringer og lærer hvordan du kan bevare en aktivitets tilstand som svar på enhetskonfigurasjonsendringer og andre aktivitetslivssyklushendelser.
I denne praktiske artikkelen legger du til loggsetninger til TwoActivities-appen og observerer endringer i aktivitetslivssyklusen mens du bruker appen. Deretter begynner du å jobbe med disse endringene og utforske hvordan du håndterer brukerinnspill under disse forholdene.
Forutsetninger
Du bør kunne:
- Opprett og kjør et appprosjekt i Android Studio .
- Legg til loggsetninger i appen din og se loggene i Logcat-ruten.
- Forstå og arbeid med en aktivitet og en intensjon, og vær komfortabel med å samhandle med dem.
Hva du vil lære
- Hvordan Aktivitets livssyklus fungerer.
- Når en aktivitet starter, stopper, stopper og blir ødelagt.
- Om tilbakeringingsmetodene for livssyklusen knyttet til aktivitetsendringer.
- Effekten av handlinger (som konfigurasjonsendringer) som kan resultere i aktivitetslivssyklushendelser.
- Hvordan beholde aktivitetsstatus på tvers av livssyklushendelser.
Hva du skal gjøre
- Legg til kode i TwoActivities -appen fra forrige praktiske for å implementere de ulike aktivitetslivssyklustilbakekallingene for å inkludere loggingssetninger.
- Observer tilstandsendringene mens appen din kjører og når du samhandler med hver aktivitet i appen din.
- Endre appen din for å beholde forekomsttilstanden til en aktivitet som uventet gjenskapes som svar på brukeratferd eller konfigurasjonsendring på enheten.
2. App-oversikt
I dette praktiske legger du til TwoActivities -appen. Appen ser ut og oppfører seg omtrent på samme måte som den gjorde i forrige codelab. Den inneholder to Activity-implementeringer og gir brukeren muligheten til å sende mellom dem. Endringene du gjør i appen i denne praktiske appen vil ikke påvirke den synlige brukeratferden.
3. 3. Oppgave 1: Legg til livssyklus tilbakeringinger til TwoActivities
I denne oppgaven skal du implementere alle tilbakeringingsmetodene for aktivitetslivssyklusen for å skrive ut meldinger til logcat når disse metodene påkalles. Disse loggmeldingene lar deg se når aktivitetens livssyklus endrer tilstand, og hvordan disse livssyklustilstandsendringene påvirker appen din mens den kjører.
1.1 (Valgfritt) Kopier TwoActivities-prosjektet
For oppgavene i denne praksisen, vil du modifisere det eksisterende TwoActivities -prosjektet du bygde i den siste praktiske. Hvis du foretrekker å beholde det forrige TwoActivities-prosjektet intakt, følg trinnene i Vedlegg: Verktøy for å lage en kopi av prosjektet.
1.2 Implementer tilbakeringinger i MainActivity
- Åpne TwoActivities-prosjektet i Android Studio, og åpne MainActivity i Prosjekt > Android-panelet.
- I onCreate()-metoden legger du til følgende loggsetninger:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
- Legg til en overstyring for onStart()-tilbakekallingen, med en uttalelse til loggen for den hendelsen:
@Override
public void onStart(){
super.onStart();
Log.d(LOG_TAG, "onStart");
}
For en snarvei, velg Kode > Overstyr metoder i Android Studio. En dialogboks vises med alle de mulige metodene du kan overstyre i klassen din. Ved å velge en eller flere tilbakeringingsmetoder fra listen setter du inn en komplett mal for disse metodene, inkludert det nødvendige kallet til superklassen.
- Bruk onStart()-metoden som en mal for å implementere onPause(), onRestart(), onResume(), onStop() og onDestroy() livssyklustilbakekallinger
Alle tilbakeringingsmetodene har samme signaturer (bortsett fra navnet). Hvis du kopierer og limer inn onStart() for å lage disse andre tilbakeringingsmetodene, ikke glem å oppdatere innholdet for å kalle den riktige metoden i superklassen, og for å logge den riktige metoden.
- Kjør appen din.
- Klikk på Logcat-fanen nederst i Android Studio for å vise Logcat-ruten. Du skal se tre loggmeldinger som viser de tre livssyklustilstandene aktiviteten har gått gjennom da den startet:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume
1.3 Implementer tilbakeringing av livssyklus i SecondActivity
Nå som du har implementert metodene for tilbakeringing av livssyklusen for MainActivity, gjør du det samme for SecondActivity.
- Åpne SecondActivity.
- Øverst i klassen legger du til en konstant for LOG_TAG-variabelen:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
- Legg til livssyklus-tilbakringing og loggsetninger til den andre aktiviteten. (Du kan kopiere og lime inn tilbakeringingsmetodene fra MainActivity.)
- Legg til en loggsetning til returnReply()-metoden like før finish()-metoden:
Log.d(LOG_TAG, "End SecondActivity");
1.4 Observer loggen mens appen kjører**
- Kjør appen din.
- Klikk på Logcat-fanen nederst i Android Studio for å vise Logcat-ruten.
- Skriv inn aktivitet i søkefeltet. Android logcat kan være veldig lang og rotete. Fordi LOG_TAG-variabelen i hver klasse inneholder enten ordene MainActivity eller SecondActivity, lar dette søkeordet deg filtrere loggen for bare de tingene du er interessert i.
Eksperimenter med appen din og merk at livssyklushendelsene som oppstår som svar på forskjellige handlinger. Prøv spesielt disse tingene:
- Bruk appen normalt (send en melding, svar med en annen melding).
- Bruk Tilbake-knappen for å gå tilbake fra den andre aktiviteten til hovedaktiviteten.
- Bruk opp-pilen i applinjen for å gå tilbake fra den andre aktiviteten til hovedaktiviteten.
- Roter enheten på både hovedaktiviteten og den andre aktiviteten til forskjellige tider i appen din og observer hva som skjer i * loggen og på skjermen.
- Trykk på oversiktsknappen (den firkantede knappen til høyre for Hjem) og lukk appen (trykk på X).
- Gå tilbake til startskjermen og start appen på nytt.
TIPS: Hvis du kjører appen din i en emulator, kan du simulere rotasjon med Control+F11 eller Control+Function+F11.
Oppgave 1 løsningskode
Følgende kodebiter viser løsningskoden for den første oppgaven.
Hovedaktivitet
Følgende kodebiter viser den tillagte koden i MainActivity, men ikke hele klassen.
onCreate()-metoden:
@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);
}
De andre livssyklusmetodene:
@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");
}
SecondActivity
Følgende kodebiter viser den tillagte koden i SecondActivity, men ikke hele klassen.
På toppen av SecondActivity-klassen:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
ReturnReply()-metoden:
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();
}
De andre livssyklusmetodene:
Samme som for MainActivity, ovenfor.
4. 4. Oppgave 2: Lagre og gjenopprett aktivitetsforekomsttilstanden
Avhengig av systemressurser og brukeratferd, kan hver aktivitet i appen din bli ødelagt og rekonstruert mye oftere enn du kanskje tror.
Du har kanskje lagt merke til denne oppførselen i den siste delen da du roterte enheten eller emulatoren. Rotering av enheten er ett eksempel på endring av enhetskonfigurasjon. Selv om rotasjon er den vanligste, resulterer alle konfigurasjonsendringer i at den nåværende aktiviteten blir ødelagt og gjenskapt som om den var ny. Hvis du ikke tar hensyn til denne oppførselen i koden din, når det skjer en konfigurasjonsendring, kan aktivitetsoppsettet ditt gå tilbake til standardutseende og startverdier, og brukerne dine kan miste plassen sin, dataene eller statusen til fremdriften i appen din.
Tilstanden til hver aktivitet lagres som et sett med nøkkel/verdi-par i et Bundle-objekt kalt Aktivitetsforekomsttilstanden. Systemet lagrer standardtilstandsinformasjon til instanstilstandspakke rett før aktiviteten stoppes, og sender denne pakken til den nye aktivitetsforekomsten for å gjenopprette.
For å unngå å miste data i en aktivitet når den uventet blir ødelagt og gjenskapt, må du implementere onSaveInstanceState()-metoden. Systemet kaller denne metoden på aktiviteten din (mellom onPause() og onStop()) når det er en mulighet for at aktiviteten kan bli ødelagt og gjenskapt.
Dataene du lagrer i forekomsttilstanden, er spesifikke for bare denne forekomsten av denne spesifikke aktiviteten under gjeldende appøkt. Når du stopper og starter en ny appøkt på nytt, går aktivitetsforekomsttilstanden tapt og aktiviteten går tilbake til standardutseendet. Hvis du trenger å lagre brukerdata mellom appøkter, bruk delte preferanser eller en database. Du lærer om begge disse i en senere praksis.
2.1 Lagre aktivitetsforekomsttilstanden med onSaveInstanceState()
Du har kanskje lagt merke til at rotering av enheten ikke påvirker tilstanden til den andre aktiviteten i det hele tatt. Dette er fordi det andre aktivitetsoppsettet og tilstanden genereres fra oppsettet og intensjonen som aktiverte den. Selv om aktiviteten gjenskapes, er intensjonen fortsatt der, og dataene i den hensikten brukes fortsatt hver gang onCreate()-metoden i den andre aktiviteten kalles.
I tillegg kan du legge merke til at i hver aktivitet beholdes all tekst du skrev inn i meldinger eller svar EditText-elementer selv når enheten roteres. Dette er fordi tilstandsinformasjonen til noen av View-elementene i layouten din lagres automatisk på tvers av konfigurasjonsendringer, og den gjeldende verdien av en EditText er et av disse tilfellene.
Så den eneste aktivitetstilstanden du er interessert i er TextView-elementene for svaroverskriften og svarteksten i hovedaktiviteten. Begge TextView-elementene er usynlige som standard; de vises bare når du sender en melding tilbake til hovedaktiviteten fra den andre aktiviteten.
I denne oppgaven legger du til kode for å bevare forekomsttilstanden til disse to TextView-elementene ved å bruke onSaveInstanceState().
- Åpne MainActivity.
- Legg til denne skjelettimplementeringen av onSaveInstanceState() til aktiviteten, eller bruk Kode > Overstyringsmetoder for å sette inn en skjelettoverstyring.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
- Sjekk for å se om overskriften er synlig for øyeblikket, og i så fall legg den synlighetstilstanden inn i tilstandspakken med putBoolean()-metoden og nøkkelen "reply_visible".
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
}
Husk at svaroverskriften og teksten er merket som usynlig inntil det kommer et svar fra den andre aktiviteten. Hvis overskriften er synlig, er det svardata som må lagres. Merk at vi bare er interessert i den synlighetstilstanden - selve teksten i overskriften trenger ikke å lagres, fordi den teksten aldri endres.
- I den samme sjekken legger du til svarteksten i pakken.
outState.putString("reply_text",mReplyTextView.getText().toString());
Hvis overskriften er synlig kan du anta at selve svarmeldingen også er synlig. Du trenger ikke å teste for eller lagre gjeldende synlighetsstatus for svarmeldingen. Bare selve teksten i meldingen går inn i tilstandspakken med nøkkelen "reply_text".
Du lagrer kun tilstanden til de View-elementene som kan endres etter at aktiviteten er opprettet. De andre View-elementene i appen din (Redigeringsteksten, knappen) kan gjenskapes fra standardoppsettet når som helst.
Merk at systemet vil lagre tilstanden til enkelte View-elementer, for eksempel innholdet i EditText.
2.2 Gjenopprett aktivitetsforekomsttilstanden i onCreate()
Når du har lagret aktivitetsforekomsttilstanden, må du også gjenopprette den når aktiviteten gjenopprettes. Du kan gjøre dette enten i onCreate(), eller ved å implementere tilbakekallingen onRestoreInstanceState(), som kalles opp etter onStart() etter at aktiviteten er opprettet.
Mesteparten av tiden er det bedre stedet å gjenopprette aktivitetstilstanden i onCreate(), for å sikre at brukergrensesnittet, inkludert tilstanden, er tilgjengelig så snart som mulig. Noen ganger er det praktisk å gjøre det i onRestoreInstanceState() etter at all initialiseringen er utført, eller å la underklasser bestemme om de skal bruke standardimplementeringen.
- I onCreate()-metoden, etter at View-variablene er initialisert med findViewById(), legger du til en test for å sikre at savedInstanceState ikke er null.
// 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) {
}
Når aktiviteten din er opprettet, sender systemet tilstandspakken til onCreate() som eneste argument. Første gang onCreate() kalles og appen din starter, er pakken null – det er ingen eksisterende tilstand første gang appen din starter. Påfølgende kall til onCreate() har en bunt fylt med dataene du har lagret i onSaveInstanceState().
- Inne i den sjekken, få gjeldende synlighet (sant eller usant) ut av pakken med nøkkelen "reply_visible".
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
}
- Legg til en test under den forrige linjen for variabelen isVisible.
if (isVisible) {
}
Hvis det er en reply_visible-nøkkel i tilstandspakken (og isVisible er derfor sant), må du gjenopprette tilstanden.
- Gjør overskriften synlig i isVisible-testen.
mReplyHeadTextView.setVisibility(View.VISIBLE);
- Få tekstsvarmeldingen fra pakken med nøkkelen "reply_text", og still inn svaret TextView til å vise den strengen.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
- Gjør også svaret TextView synlig:
mReplyTextView.setVisibility(View.VISIBLE);
- Kjør appen. Prøv å rotere enheten eller emulatoren for å sikre at svarmeldingen (hvis det er en) forblir på skjermen etter at aktiviteten er gjenskapt.
Oppgave 2 løsningskode
Følgende kodebiter viser løsningskoden for denne oppgaven.
Hovedaktivitet
Følgende kodebiter viser den tillagte koden i MainActivity, men ikke hele klassen.
OnSaveInstanceState()-metoden:
@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());
}
}
onCreate()-metoden:
@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);
}
}
}
Det komplette prosjektet:
Android Studio Project: TwoActivitiesLifecycle
5. Koding
Utfordring: Lag en enkel handleliste-app med en hovedaktivitet for listen brukeren bygger, og en andre aktivitet for en liste over vanlige handlevarer.
- Hovedaktiviteten bør inneholde listen som skal bygges, som skal bestå av ti tomme TextView-elementer.
- En Add Item-knapp på hovedaktiviteten starter en annen aktivitet som inneholder en liste over vanlige handlevarer (ost, ris, epler og så videre). Bruk knappeelementer for å vise elementene.
- Ved å velge et element returnerer brukeren til hovedaktiviteten, og oppdaterer en tom tekstvisning for å inkludere det valgte elementet.
Bruk en intensjon for å overføre informasjon fra en aktivitet til en annen. Sørg for at gjeldende status for handlelisten er lagret når brukeren roterer enheten.
6. Sammendrag
- Aktivitetslivssyklusen er et sett med tilstander en aktivitet migrerer gjennom, som begynner når den først opprettes og slutter når Android-systemet tar tilbake ressursene for den aktiviteten.
- Når brukeren navigerer fra en aktivitet til en annen, og i og utenfor appen din, flytter hver aktivitet mellom tilstander i aktivitetslivssyklusen.
- Hver tilstand i aktivitetslivssyklusen har en tilsvarende tilbakeringingsmetode du kan overstyre i aktivitetsklassen din.
- Livssyklusmetodene er onCreate(), onStart(), onPause(), onRestart(), onResume(), onStop(), onDestroy().
- Ved å overstyre en tilbakeringingsmetode for livssyklus kan du legge til atferd som oppstår når aktiviteten din går over til den tilstanden.
- Du kan legge til skjelettoverstyringsmetoder i klassene dine i Android Studio med Kode > Overstyr.
- Endringer i enhetskonfigurasjonen som rotasjon resulterer i at aktiviteten blir ødelagt og gjenskapt som om den var ny.
- En del av aktivitetstilstanden blir bevart ved en konfigurasjonsendring, inkludert gjeldende verdier til EditText-elementer. For alle andre data må du eksplisitt lagre disse dataene selv.
- Lagre aktivitetsforekomsttilstand i onSaveInstanceState()-metoden.
- Forekomsttilstandsdata lagres som enkle nøkkel/verdi-par i en pakke. Bruk Bundle-metodene for å legge data inn i og få data tilbake ut av Bundle.
- Gjenopprett forekomsttilstanden i onCreate(), som er den foretrukne måten, eller onRestoreInstanceState(). Tilbake
1. Velkommen
Denne praktiske kodelabben er en del av Unit 1: Kom i gang med Android Developer Fundamentals (versjon 2)-kurset. Du vil få mest mulig ut av dette kurset hvis du arbeider gjennom kodelabbene i rekkefølge:
- For den fullstendige listen over kodelaber i kurset, se Codelabs for Android Developer Fundamentals (V2).
- For detaljer om kurset, inkludert lenker til alle konseptkapitlene, appene og lysbildene, se Android Developer Fundamentals (versjon 2).
Introduksjon
I denne øvelsen lærer du mer om aktivitetens livssyklus. Livssyklusen er settet med tilstander en aktivitet kan være i gjennom hele levetiden, fra den er opprettet til den blir ødelagt og systemet tar tilbake ressursene sine. Når en bruker navigerer mellom aktiviteter i appen din (så vel som inn og ut av appen), går aktiviteter over mellom ulike tilstander i livssyklusen.
Hvert trinn i en aktivitets livssyklus har en tilsvarende tilbakeringingsmetode: onCreate(), onStart(), onPause() og så videre. Når en aktivitet endrer tilstand, aktiveres den tilknyttede tilbakeringingsmetoden. Du har allerede sett en av disse metodene: onCreate(). Ved å overstyre noen av tilbakeringingsmetodene for livssyklusen i aktivitetsklassene dine, kan du endre aktivitetens standardoppførsel som svar på bruker- eller systemhandlinger.
Aktivitetstilstanden kan også endres som svar på endringer i enhetskonfigurasjonen, for eksempel når brukeren roterer enheten fra stående til liggende. Når disse konfigurasjonsendringene skjer, blir aktiviteten ødelagt og gjenskapt i standardtilstanden, og brukeren kan miste informasjon som de har lagt inn i aktiviteten. For å unngå å forvirre brukerne dine, er det viktig at du utvikler appen din for å forhindre uventet tap av data. Senere i dette praktiske eksperimentet eksperimenterer du med konfigurasjonsendringer og lærer hvordan du kan bevare en aktivitets tilstand som svar på enhetskonfigurasjonsendringer og andre aktivitetslivssyklushendelser.
I denne praktiske artikkelen legger du til loggsetninger til TwoActivities-appen og observerer endringer i aktivitetslivssyklusen mens du bruker appen. Deretter begynner du å jobbe med disse endringene og utforske hvordan du håndterer brukerinnspill under disse forholdene.
Forutsetninger
Du bør kunne:
- Opprett og kjør et appprosjekt i Android Studio .
- Legg til loggsetninger i appen din og se loggene i Logcat-ruten.
- Forstå og arbeid med en aktivitet og en intensjon, og vær komfortabel med å samhandle med dem.
Hva du vil lære
- Hvordan Aktivitets livssyklus fungerer.
- Når en aktivitet starter, stopper, stopper og blir ødelagt.
- Om tilbakeringingsmetodene for livssyklusen knyttet til aktivitetsendringer.
- Effekten av handlinger (som konfigurasjonsendringer) som kan resultere i aktivitetslivssyklushendelser.
- Hvordan beholde aktivitetsstatus på tvers av livssyklushendelser.
Hva du skal gjøre
- Legg til kode i TwoActivities -appen fra forrige praktiske for å implementere de ulike aktivitetslivssyklustilbakekallingene for å inkludere loggingssetninger.
- Observer tilstandsendringene mens appen din kjører og når du samhandler med hver aktivitet i appen din.
- Endre appen din for å beholde forekomsttilstanden til en aktivitet som uventet gjenskapes som svar på brukeratferd eller konfigurasjonsendring på enheten.
2. App-oversikt
I dette praktiske legger du til TwoActivities -appen. Appen ser ut og oppfører seg omtrent på samme måte som den gjorde i forrige codelab. Den inneholder to Activity-implementeringer og gir brukeren muligheten til å sende mellom dem. Endringene du gjør i appen i denne praktiske appen vil ikke påvirke den synlige brukeratferden.
3. 3. Oppgave 1: Legg til livssyklus tilbakeringinger til TwoActivities
I denne oppgaven skal du implementere alle tilbakeringingsmetodene for aktivitetslivssyklusen for å skrive ut meldinger til logcat når disse metodene påkalles. Disse loggmeldingene lar deg se når aktivitetens livssyklus endrer tilstand, og hvordan disse livssyklustilstandsendringene påvirker appen din mens den kjører.
1.1 (Valgfritt) Kopier TwoActivities-prosjektet
For oppgavene i denne praksisen, vil du modifisere det eksisterende TwoActivities -prosjektet du bygde i den siste praktiske. Hvis du foretrekker å beholde det forrige TwoActivities-prosjektet intakt, følg trinnene i Vedlegg: Verktøy for å lage en kopi av prosjektet.
1.2 Implementer tilbakeringinger i MainActivity
- Åpne TwoActivities-prosjektet i Android Studio, og åpne MainActivity i Prosjekt > Android-panelet.
- I onCreate()-metoden legger du til følgende loggsetninger:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
- Legg til en overstyring for onStart()-tilbakekallingen, med en uttalelse til loggen for den hendelsen:
@Override
public void onStart(){
super.onStart();
Log.d(LOG_TAG, "onStart");
}
For en snarvei, velg Kode > Overstyr metoder i Android Studio. En dialogboks vises med alle de mulige metodene du kan overstyre i klassen din. Ved å velge en eller flere tilbakeringingsmetoder fra listen setter du inn en komplett mal for disse metodene, inkludert det nødvendige kallet til superklassen.
- Bruk onStart()-metoden som en mal for å implementere onPause(), onRestart(), onResume(), onStop() og onDestroy() livssyklustilbakekallinger
Alle tilbakeringingsmetodene har samme signaturer (bortsett fra navnet). Hvis du kopierer og limer inn onStart() for å lage disse andre tilbakeringingsmetodene, ikke glem å oppdatere innholdet for å kalle den riktige metoden i superklassen, og for å logge den riktige metoden.
- Kjør appen din.
- Klikk på Logcat-fanen nederst i Android Studio for å vise Logcat-ruten. Du skal se tre loggmeldinger som viser de tre livssyklustilstandene aktiviteten har gått gjennom da den startet:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume
1.3 Implementer tilbakeringing av livssyklus i SecondActivity
Nå som du har implementert metodene for tilbakeringing av livssyklusen for MainActivity, gjør du det samme for SecondActivity.
- Åpne SecondActivity.
- Øverst i klassen legger du til en konstant for LOG_TAG-variabelen:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
- Legg til livssyklus-tilbakringing og loggsetninger til den andre aktiviteten. (Du kan kopiere og lime inn tilbakeringingsmetodene fra MainActivity.)
- Legg til en loggsetning til returnReply()-metoden like før finish()-metoden:
Log.d(LOG_TAG, "End SecondActivity");
1.4 Observer loggen mens appen kjører**
- Kjør appen din.
- Klikk på Logcat-fanen nederst i Android Studio for å vise Logcat-ruten.
- Skriv inn aktivitet i søkefeltet. Android logcat kan være veldig lang og rotete. Fordi LOG_TAG-variabelen i hver klasse inneholder enten ordene MainActivity eller SecondActivity, lar dette søkeordet deg filtrere loggen for bare de tingene du er interessert i.
Eksperimenter med appen din og merk at livssyklushendelsene som oppstår som svar på forskjellige handlinger. Prøv spesielt disse tingene:
- Bruk appen normalt (send en melding, svar med en annen melding).
- Bruk Tilbake-knappen for å gå tilbake fra den andre aktiviteten til hovedaktiviteten.
- Bruk opp-pilen i applinjen for å gå tilbake fra den andre aktiviteten til hovedaktiviteten.
- Roter enheten på både hovedaktiviteten og den andre aktiviteten til forskjellige tider i appen din og observer hva som skjer i * loggen og på skjermen.
- Trykk på oversiktsknappen (den firkantede knappen til høyre for Hjem) og lukk appen (trykk på X).
- Gå tilbake til startskjermen og start appen på nytt.
TIPS: Hvis du kjører appen din i en emulator, kan du simulere rotasjon med Control+F11 eller Control+Function+F11.
Oppgave 1 løsningskode
Følgende kodebiter viser løsningskoden for den første oppgaven.
Hovedaktivitet
Følgende kodebiter viser den tillagte koden i MainActivity, men ikke hele klassen.
onCreate()-metoden:
@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);
}
De andre livssyklusmetodene:
@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");
}
SecondActivity
Følgende kodebiter viser den tillagte koden i SecondActivity, men ikke hele klassen.
På toppen av SecondActivity-klassen:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
ReturnReply()-metoden:
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();
}
De andre livssyklusmetodene:
Samme som for MainActivity, ovenfor.
4. 4. Oppgave 2: Lagre og gjenopprett aktivitetsforekomsttilstanden
Avhengig av systemressurser og brukeratferd, kan hver aktivitet i appen din bli ødelagt og rekonstruert mye oftere enn du kanskje tror.
Du har kanskje lagt merke til denne oppførselen i den siste delen da du roterte enheten eller emulatoren. Rotering av enheten er ett eksempel på endring av enhetskonfigurasjon. Selv om rotasjon er den vanligste, resulterer alle konfigurasjonsendringer i at den nåværende aktiviteten blir ødelagt og gjenskapt som om den var ny. Hvis du ikke tar hensyn til denne oppførselen i koden din, når det skjer en konfigurasjonsendring, kan aktivitetsoppsettet ditt gå tilbake til standardutseende og startverdier, og brukerne dine kan miste plassen sin, dataene eller statusen til fremdriften i appen din.
Tilstanden til hver aktivitet lagres som et sett med nøkkel/verdi-par i et Bundle-objekt kalt Aktivitetsforekomsttilstanden. Systemet lagrer standardtilstandsinformasjon til instanstilstandspakke rett før aktiviteten stoppes, og sender denne pakken til den nye aktivitetsforekomsten for å gjenopprette.
For å unngå å miste data i en aktivitet når den uventet blir ødelagt og gjenskapt, må du implementere onSaveInstanceState()-metoden. Systemet kaller denne metoden på aktiviteten din (mellom onPause() og onStop()) når det er en mulighet for at aktiviteten kan bli ødelagt og gjenskapt.
Dataene du lagrer i forekomsttilstanden, er spesifikke for bare denne forekomsten av denne spesifikke aktiviteten under gjeldende appøkt. Når du stopper og starter en ny appøkt på nytt, går aktivitetsforekomsttilstanden tapt og aktiviteten går tilbake til standardutseendet. Hvis du trenger å lagre brukerdata mellom appøkter, bruk delte preferanser eller en database. Du lærer om begge disse i en senere praksis.
2.1 Lagre aktivitetsforekomsttilstanden med onSaveInstanceState()
Du har kanskje lagt merke til at rotering av enheten ikke påvirker tilstanden til den andre aktiviteten i det hele tatt. Dette er fordi det andre aktivitetsoppsettet og tilstanden genereres fra oppsettet og intensjonen som aktiverte den. Selv om aktiviteten gjenskapes, er intensjonen fortsatt der, og dataene i den hensikten brukes fortsatt hver gang onCreate()-metoden i den andre aktiviteten kalles.
I tillegg kan du legge merke til at i hver aktivitet beholdes all tekst du skrev inn i meldinger eller svar EditText-elementer selv når enheten roteres. Dette er fordi tilstandsinformasjonen til noen av View-elementene i layouten din lagres automatisk på tvers av konfigurasjonsendringer, og den gjeldende verdien av en EditText er et av disse tilfellene.
Så den eneste aktivitetstilstanden du er interessert i er TextView-elementene for svaroverskriften og svarteksten i hovedaktiviteten. Begge TextView-elementene er usynlige som standard; de vises bare når du sender en melding tilbake til hovedaktiviteten fra den andre aktiviteten.
I denne oppgaven legger du til kode for å bevare forekomsttilstanden til disse to TextView-elementene ved å bruke onSaveInstanceState().
- Åpne MainActivity.
- Legg til denne skjelettimplementeringen av onSaveInstanceState() til aktiviteten, eller bruk Kode > Overstyringsmetoder for å sette inn en skjelettoverstyring.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
- Sjekk for å se om overskriften er synlig for øyeblikket, og i så fall legg den synlighetstilstanden inn i tilstandspakken med putBoolean()-metoden og nøkkelen "reply_visible".
if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
outState.putBoolean("reply_visible", true);
}
Husk at svaroverskriften og teksten er merket som usynlig inntil det kommer et svar fra den andre aktiviteten. Hvis overskriften er synlig, er det svardata som må lagres. Merk at vi bare er interessert i den synlighetstilstanden - selve teksten i overskriften trenger ikke å lagres, fordi den teksten aldri endres.
- I den samme sjekken legger du til svarteksten i pakken.
outState.putString("reply_text",mReplyTextView.getText().toString());
Hvis overskriften er synlig kan du anta at selve svarmeldingen også er synlig. Du trenger ikke å teste for eller lagre gjeldende synlighetsstatus for svarmeldingen. Bare selve teksten i meldingen går inn i tilstandspakken med nøkkelen "reply_text".
Du lagrer kun tilstanden til de View-elementene som kan endres etter at aktiviteten er opprettet. De andre View-elementene i appen din (Redigeringsteksten, knappen) kan gjenskapes fra standardoppsettet når som helst.
Merk at systemet vil lagre tilstanden til enkelte View-elementer, for eksempel innholdet i EditText.
2.2 Gjenopprett aktivitetsforekomsttilstanden i onCreate()
Når du har lagret aktivitetsforekomsttilstanden, må du også gjenopprette den når aktiviteten gjenopprettes. Du kan gjøre dette enten i onCreate(), eller ved å implementere tilbakekallingen onRestoreInstanceState(), som kalles opp etter onStart() etter at aktiviteten er opprettet.
Mesteparten av tiden er det bedre stedet å gjenopprette aktivitetstilstanden i onCreate(), for å sikre at brukergrensesnittet, inkludert tilstanden, er tilgjengelig så snart som mulig. Noen ganger er det praktisk å gjøre det i onRestoreInstanceState() etter at all initialiseringen er utført, eller å la underklasser bestemme om de skal bruke standardimplementeringen.
- I onCreate()-metoden, etter at View-variablene er initialisert med findViewById(), legger du til en test for å sikre at savedInstanceState ikke er null.
// 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) {
}
Når aktiviteten din er opprettet, sender systemet tilstandspakken til onCreate() som eneste argument. Første gang onCreate() kalles og appen din starter, er pakken null – det er ingen eksisterende tilstand første gang appen din starter. Påfølgende kall til onCreate() har en bunt fylt med dataene du har lagret i onSaveInstanceState().
- Inne i den sjekken, få gjeldende synlighet (sant eller usant) ut av pakken med nøkkelen "reply_visible".
if (savedInstanceState != null) {
boolean isVisible =
savedInstanceState.getBoolean("reply_visible");
}
- Legg til en test under den forrige linjen for variabelen isVisible.
if (isVisible) {
}
Hvis det er en reply_visible-nøkkel i tilstandspakken (og isVisible er derfor sant), må du gjenopprette tilstanden.
- Gjør overskriften synlig i isVisible-testen.
mReplyHeadTextView.setVisibility(View.VISIBLE);
- Få tekstsvarmeldingen fra pakken med nøkkelen "reply_text", og still inn svaret TextView til å vise den strengen.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
- Gjør også svaret TextView synlig:
mReplyTextView.setVisibility(View.VISIBLE);
- Kjør appen. Prøv å rotere enheten eller emulatoren for å sikre at svarmeldingen (hvis det er en) forblir på skjermen etter at aktiviteten er gjenskapt.
Oppgave 2 løsningskode
Følgende kodebiter viser løsningskoden for denne oppgaven.
Hovedaktivitet
Følgende kodebiter viser den tillagte koden i MainActivity, men ikke hele klassen.
OnSaveInstanceState()-metoden:
@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());
}
}
onCreate()-metoden:
@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);
}
}
}
Det komplette prosjektet:
Android Studio Project: TwoActivitiesLifecycle
5. Koding
Utfordring: Lag en enkel handleliste-app med en hovedaktivitet for listen brukeren bygger, og en andre aktivitet for en liste over vanlige handlevarer.
- Hovedaktiviteten bør inneholde listen som skal bygges, som skal bestå av ti tomme TextView-elementer.
- En Add Item-knapp på hovedaktiviteten starter en annen aktivitet som inneholder en liste over vanlige handlevarer (ost, ris, epler og så videre). Bruk knappeelementer for å vise elementene.
- Ved å velge et element returnerer brukeren til hovedaktiviteten, og oppdaterer en tom tekstvisning for å inkludere det valgte elementet.
Bruk en intensjon for å overføre informasjon fra en aktivitet til en annen. Sørg for at gjeldende status for handlelisten er lagret når brukeren roterer enheten.
6. Sammendrag
- Aktivitetslivssyklusen er et sett med tilstander en aktivitet migrerer gjennom, som begynner når den først opprettes og slutter når Android-systemet tar tilbake ressursene for den aktiviteten.
- Når brukeren navigerer fra en aktivitet til en annen, og i og utenfor appen din, flytter hver aktivitet mellom tilstander i aktivitetslivssyklusen.
- Hver tilstand i aktivitetslivssyklusen har en tilsvarende tilbakeringingsmetode du kan overstyre i aktivitetsklassen din.
- Livssyklusmetodene er onCreate(), onStart(), onPause(), onRestart(), onResume(), onStop(), onDestroy().
- Ved å overstyre en tilbakeringingsmetode for livssyklus kan du legge til atferd som oppstår når aktiviteten din går over til den tilstanden.
- Du kan legge til skjelettoverstyringsmetoder i klassene dine i Android Studio med Kode > Overstyr.
- Endringer i enhetskonfigurasjonen som rotasjon resulterer i at aktiviteten blir ødelagt og gjenskapt som om den var ny.
- En del av aktivitetstilstanden blir bevart ved en konfigurasjonsendring, inkludert gjeldende verdier til EditText-elementer. For alle andre data må du eksplisitt lagre disse dataene selv.
- Lagre aktivitetsforekomsttilstand i onSaveInstanceState()-metoden.
- Forekomsttilstandsdata lagres som enkle nøkkel/verdi-par i en pakke. Bruk Bundle-metodene for å legge data inn i og få data tilbake ut av Bundle.
- Gjenopprett forekomsttilstanden i onCreate(), som er den foretrukne måten, eller onRestoreInstanceState(). Tilbake