Како се користи животни циклус и стање активности, како се користи животни циклус и стање активности

1. Добродошли

Ова практична лабораторија кода је део јединице 1: Започните на курсу Андроид Девелопер Фундаменталс (верзија 2). Добићете највећу вредност од овог курса ако радите кроз лабораторије кодова у низу:

  • За комплетну листу кодних лабораторија у оквиру курса, погледајте Цоделабс фор Андроид Девелопер Фундаменталс (В2).
  • За детаље о курсу, укључујући везе ка свим поглављима концепта, апликацијама и слајдовима, погледајте Основе Андроид програмера (верзија 2).

Увод

У овој пракси сазнаћете више о животном циклусу активности. Животни циклус је скуп стања у којима активност може да буде током читавог свог животног века, од тренутка када је створена до тренутка када је уништена и када систем поврати своје ресурсе. Док се корисник креће између активности у вашој апликацији (као и у вашу апликацију и ван ње), активности прелазе између различитих стања у свом животном циклусу.

Двострука невоља

Свака фаза у животном циклусу активности има одговарајући метод повратног позива: онЦреате(), онСтарт(), онПаусе(), итд. Када активност промени стање, позива се придружени метод повратног позива. Већ сте видели један од ових метода: онЦреате(). Поништавањем било које методе повратног позива животног циклуса у вашим класама активности, можете променити подразумевано понашање активности као одговор на радње корисника или система.

Стање активности се такође може променити као одговор на промене у конфигурацији уређаја, на пример када корисник ротира уређај из усправног у пејзаж. Када се догоде ове промене конфигурације, активност се уништава и поново креира у свом подразумеваном стању, а корисник може да изгуби информације које је унео у активност. Да не бисте збунили кориснике, важно је да развијете своју апликацију како бисте спречили неочекивани губитак података. Касније у овој пракси експериментишете са променама конфигурације и научите како да сачувате стање активности као одговор на промене конфигурације уређаја и друге догађаје животног циклуса активности.

У овој пракси додајете изјаве за евидентирање у апликацију ТвоАцтивитиес и посматрате промене животног циклуса активности док користите апликацију. Затим почињете да радите са овим променама и да истражујете како да рукујете уносом корисника у овим условима.

Предуслови

Требало би да будете у могућности да:

  • Креирајте и покрените пројекат апликације у Андроид Студију .
  • Додајте изјаве дневника у своју апликацију и прегледајте те евиденције у окну Логцат.
  • Разумети активност и намеру и радити са њима и бити пријатни у интеракцији са њима.

Шта ћете научити

  • Како функционише животни циклус активности.
  • Када се активност покрене, паузира, зауставља и уништава.
  • О методама повратног позива животног циклуса повезаних са променама активности.
  • Ефекат радњи (као што су промене конфигурације) које могу довести до догађаја животног циклуса активности.
  • Како задржати стање активности током догађаја животног циклуса.

Шта ћеш урадити

  • Додајте код у апликацију ТвоАцтивитиес из претходне практичне да бисте имплементирали различите повратне позиве животног циклуса активности да бисте укључили изјаве за евидентирање.
  • Посматрајте промене стања док се апликација покреће и док остварујете интеракцију са сваком активношћу у апликацији.
  • Измените своју апликацију да задржите стање инстанце активности која се неочекивано поново креира као одговор на понашање корисника или промену конфигурације на уређају.

2. Преглед апликације

У овој пракси додајете у апликацију ТвоАцтивитиес . Апликација изгледа и понаша се отприлике исто као у прошлој лабораторији кодова. Садржи две имплементације активности и даје кориснику могућност да шаље између њих. Промене које унесете у апликацију у овој пракси неће утицати на њено видљиво понашање корисника.

3. 3. Задатак 1: Додајте повратне позиве животног циклуса у ТвоАцтивитиес

У овом задатку ћете имплементирати све методе повратног позива животног циклуса активности за штампање порука у логцат када се те методе позову. Ове поруке дневника ће вам омогућити да видите када животни циклус активности мења стање и како те промене стања животног циклуса утичу на вашу апликацију док она ради.

1.1 (Опционо) Копирајте пројекат ТвоАцтивитиес

За задатке у овој пракси, модификоваћете постојећи ТвоАцтивитиес пројекат који сте изградили у последњој пракси. Ако желите да претходни ТвоАцтивитиес пројекат остане нетакнут, пратите кораке у Додатку: Услужни програми да бисте направили копију пројекта.

1.2 Имплементирајте повратне позиве у МаинАцтивити

  1. Отворите пројекат ТвоАцтивитиес у Андроид студију и отворите МаинАцтивити у окну Пројецт > Андроид.
  2. У методу онЦреате() додајте следеће изјаве дневника:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
  1. Додајте замена за онСтарт() повратни позив, са наредбом у дневник за тај догађај:
@Override
public void onStart(){
    super.onStart();
    Log.d(LOG_TAG, "onStart");
}

За пречицу изаберите Цоде > Оверриде Метходс у Андроид Студију. Појављује се дијалог са свим могућим методама које можете заменити у својој класи. Одабиром једне или више метода повратног позива са листе убацује се комплетан шаблон за те методе, укључујући и потребан позив суперкласи.

  1. Користите онСтарт() метод као шаблон за имплементацију повратних позива животног циклуса онПаусе(), онРестарт(), онРесуме(), онСтоп() и онДестрои()

Све методе повратног позива имају исте потписе (осим имена). Ако копирате и налепите онСтарт() да бисте креирали ове друге методе повратног позива, не заборавите да ажурирате садржај да бисте позвали прави метод у суперкласи и да бисте евидентирали исправан метод.

  1. Покрените своју апликацију.
  2. Кликните на картицу Логцат на дну Андроид Студија да бисте приказали окно Логцат. Требало би да видите три дневник поруке које приказују три стања животног циклуса кроз која је активност прешла на почетку:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume

1.3 Имплементирајте повратне позиве животног циклуса у СецондАцтивити

Сада када сте имплементирали методе повратног позива животног циклуса за МаинАцтивити, урадите исто за СецондАцтивити.

  1. Отворите СецондАцтивити.
  2. На врх класе додајте константу за променљиву ЛОГ_ТАГ:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
  1. Додајте повратне позиве животног циклуса и изјаве дневника у другу активност. (Можете да копирате и налепите методе повратног позива из МаинАцтивити.)
  2. Додајте исказ дневника методи ретурнРепли() непосредно пре методе финисх():
Log.d(LOG_TAG, "End SecondActivity");

1.4 Посматрајте евиденцију док апликација ради**

  1. Покрените своју апликацију.
  2. Кликните на картицу Логцат на дну Андроид Студија да бисте приказали окно Логцат.
  3. Унесите Активност у поље за претрагу. Андроид логцат може бити веома дугачак и претрпан. Пошто променљива ЛОГ_ТАГ у свакој класи садржи речи МаинАцтивити или СецондАцтивити, ова кључна реч вам омогућава да филтрирате евиденцију само за оно што вас занима.

Двострука невоља

Експериментишите користећи своју апликацију и запазите да се догађаји животног циклуса дешавају као одговор на различите радње. Конкретно, пробајте ове ствари:

  • Користите апликацију нормално (пошаљите поруку, одговорите другом поруком).
  • Користите дугме Назад да бисте се вратили са друге активности на главну активност.
  • Користите стрелицу нагоре на траци апликација да бисте се вратили са друге активности на главну активност.
  • Ротирајте уређај на главној и другој активности у различито време у апликацији и посматрајте шта се дешава у * евиденцији и на екрану.
  • Притисните дугме за преглед (квадратно дугме десно од Хоме) и затворите апликацију (додирните Кс).
  • Вратите се на почетни екран и поново покрените апликацију.

САВЕТ: Ако своју апликацију покрећете у емулатору, можете симулирати ротацију помоћу Цонтрол+Ф11 или Цонтрол+Фунцтион+Ф11.

Шифра решења задатка 1

Следећи исечци кода приказују код решења за први задатак.

МаинАцтивити

Следећи исечци кода приказују додат код у МаинАцтивити, али не и целу класу.

Метод онЦреате():

@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);
}

Друге методе животног циклуса:

@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");
}

СецондАцтивити

Следећи исечци кода приказују додат код у СецондАцтивити, али не и целу класу.

На врху класе СецондАцтивити:

private static final String LOG_TAG = SecondActivity.class.getSimpleName();

Метод ретурнРепли():

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();
}

Друге методе животног циклуса:

Исто као за МаинАцтивити, горе.

4. 4. Задатак 2: Сачувајте и вратите стање инстанце активности

У зависности од системских ресурса и понашања корисника, свака активност у вашој апликацији може бити уништена и реконструисана много чешће него што мислите.

Можда сте приметили ово понашање у последњем одељку када сте ротирали уређај или емулатор. Ротирање уређаја је један пример промене конфигурације уређаја. Иако је ротација најчешћа, све промене конфигурације доводе до тога да се тренутна активност уништава и поново креира као да је нова. Ако не узмете у обзир ово понашање у свом коду, када дође до промене конфигурације, изглед ваше активности може да се врати на подразумевани изглед и почетне вредности, а ваши корисници могу да изгубе своје место, своје податке или стање свог напретка у ваша апликација.

Стање сваке активности се чува као скуп парова кључ/вредност у Бундле објекту који се зове стање инстанце активности. Систем чува информације о подразумеваном стању у Бундле стања инстанце непосредно пре него што се активност заустави и прослеђује тај Бундле новој инстанци активности да би се вратила.

Да не бисте изгубили податке у активности када је неочекивано уништена и поново направљена, морате да примените метод онСавеИнстанцеСтате(). Систем позива овај метод за вашу активност (између онПаусе() и онСтоп()) када постоји могућност да се активност уништи и поново креира.

Подаци које сачувате у стању инстанце су специфични само за ову инстанцу ове специфичне активности током тренутне сесије апликације. Када зауставите и поново покренете нову сесију апликације, стање инстанце активности се губи и активност се враћа на подразумевани изглед. Ако треба да сачувате корисничке податке између сесија апликације, користите дељена подешавања или базу података. О оба ова сазнаћете у каснијој пракси.

2.1 Сачувајте стање инстанце активности помоћу онСавеИнстанцеСтате()

Можда сте приметили да ротирање уређаја уопште не утиче на стање друге активности. То је зато што се други изглед и стање активности генеришу из изгледа и намере која га је активирала. Чак и ако је активност поново креирана, намера је и даље ту и подаци у тој намери се и даље користе сваки пут када се позове метод онЦреате() у другој активности.

Поред тога, можете приметити да се у свакој активности сваки текст који сте унели у поруку или одговор ЕдитТект елементи задржавају чак и када се уређај ротира. То је зато што се информације о стању неких елемената приказа у вашем распореду аутоматски чувају током промена конфигурације, а тренутна вредност ЕдитТект-а је један од тих случајева.

Дакле, једино стање активности које вас занима су елементи ТектВиев за заглавље одговора и текст одговора у главној активности. Оба елемента ТектВиев су подразумевано невидљива; појављују се само када пошаљете поруку назад главној активности из друге активности.

У овом задатку додајете код да бисте сачували стање инстанце ова два елемента ТектВиев користећи онСавеИнстанцеСтате().

  1. Отворите МаинАцтивити.
  2. Додајте ову скелетну имплементацију онСавеИнстанцеСтате() у активност или користите Цоде > Оверриде Метходс да бисте уметнули замена скелета.
@Override
public void onSaveInstanceState(Bundle outState) {
          super.onSaveInstanceState(outState);
}
  1. Проверите да ли је заглавље тренутно видљиво, и ако јесте, ставите то стање видљивости у стање Бундле са методом путБоолеан() и кључем „репли_висибле“.
 if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
        outState.putBoolean("reply_visible", true);
    }

Запамтите да су заглавље одговора и текст означени као невидљиви све док не добијете одговор из друге активности. Ако је заглавље видљиво, онда постоје подаци о одговору које треба сачувати. Имајте на уму да нас занима само то стање видљивости — стварни текст заглавља не треба да се чува, јер се тај текст никада не мења.

  1. Унутар те исте провере додајте текст одговора у пакет.
outState.putString("reply_text",mReplyTextView.getText().toString());

Ако је заглавље видљиво, можете претпоставити да је и сама порука одговора такође видљива. Не морате да тестирате нити да сачувате тренутно стање видљивости поруке одговора. Само стварни текст поруке иде у стање Бундле са кључем "репли_тект".

Чувате стање само оних елемената приказа који се могу променити након креирања активности. Остали елементи приказа у вашој апликацији (ЕдитТект, дугме) могу се поново креирати из подразумеваног изгледа у било ком тренутку.

Имајте на уму да ће систем сачувати стање неких елемената приказа, као што је садржај ЕдитТект-а.

2.2 Вратите стање инстанце активности у онЦреате()

Када сачувате стање инстанце активности, такође морате да га вратите када се активност поново креира. Ово можете да урадите или у онЦреате(), или имплементацијом повратног позива онРестореИнстанцеСтате(), који се позива након онСтарт() након што се активност креира.

Већину времена боље место за враћање стања активности је у онЦреате(), како би се осигурало да кориснички интерфејс, укључујући стање, буде доступан што је пре могуће. Понекад је згодно то урадити у онРестореИнстанцеСтате() након што је сва иницијализација обављена или дозволити подкласама да одлуче да ли ће користити вашу подразумевану имплементацију.

  1. У методи онЦреате(), након што се променљиве Виев иницијализују помоћу финдВиевБиИд(), додајте тест да бисте се уверили да саведИнстанцеСтате није нулл.
// 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) {
}

Када се ваша активност креира, систем прослеђује стање Бундле онЦреате() као једини аргумент. Када се први пут позове онЦреате() и ваша апликација се покрене, Бундле је нулл—нема постојећег стања када се апликација први пут покрене. Наредни позиви онЦреате() имају скуп попуњен подацима које сте ускладиштили у онСавеИнстанцеСтате().

  1. Унутар те провере, извадите тренутну видљивост (тачно или нетачно) из Бундле-а помоћу кључа „репли_висибле“.
if (savedInstanceState != null) {
    boolean isVisible = 
                     savedInstanceState.getBoolean("reply_visible");
}
  1. Додајте тест испод те претходне линије за променљиву исВисибле.
if (isVisible) {
}

Ако у пакету стања постоји кључ репли_висибле (и исВисибле је стога истинит), мораћете да вратите стање.

  1. Унутар теста исВисибле, учините заглавље видљивим.
mReplyHeadTextView.setVisibility(View.VISIBLE);
  1. Преузмите текстуални одговор из скупа са кључем „репли_тект“ и подесите ТектВиев одговора да приказује тај низ.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
  1. Учините и одговор ТектВиев видљивим:
mReplyTextView.setVisibility(View.VISIBLE);
  1. Покрените апликацију. Покушајте да ротирате уређај или емулатор да бисте били сигурни да порука одговора (ако постоји) остаје на екрану након што се активност поново креира.

Шифра решења задатка 2

Следећи исечци кода приказују код решења за овај задатак.

МаинАцтивити

Следећи исечци кода приказују додат код у МаинАцтивити, али не и целу класу.

Метод онСавеИнстанцеСтате():

@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());
   }
}

Метод онЦреате():

@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);
       }
   }
}

Комплетан пројекат:

Пројекат Андроид Студио: ТвоАцтивитиесЛифецицле

5. Кодирање

Изазов: Направите једноставну апликацију за листу за куповину са главном активношћу за листу коју корисник прави и другом активношћу за листу уобичајених артикала за куповину.

  • Главна активност треба да садржи листу за прављење, која треба да се састоји од десет празних ТектВиев елемената.
  • Дугме Додај ставку на главној активности покреће другу активност која садржи листу уобичајених артикала за куповину (сир, пиринач, јабуке и тако даље). Користите елементе дугмета за приказ ставки.
  • Избор ставке враћа корисника на главну активност и ажурира празан ТектВиев да би укључио изабрану ставку.

Користите намеру да пренесете информације из једне активности у другу. Уверите се да је тренутно стање листе за куповину сачувано када корисник ротира уређај.

6. Резиме

  • Животни циклус активности је скуп стања кроз које се активност мигрира, почевши од тренутка када је први пут креирана и завршавајући када Андроид систем поврати ресурсе за ту активност.
  • Док се корисник креће од једне активности до друге, унутар и ван ваше апликације, свака активност се креће између стања у животном циклусу активности.
  • Свако стање у животном циклусу активности има одговарајући метод повратног позива који можете заменити у својој класи активности.
  • Методе животног циклуса су онЦреате(), онСтарт(), онПаусе(), онРестарт(), онРесуме(), онСтоп(), онДестрои().
  • Заобилажење методе повратног позива животног циклуса вам омогућава да додате понашање које се дешава када ваша активност пређе у то стање.
  • Можете да додате методе замене скелета својим класама у Андроид Студију помоћу Цоде > Оверриде.
  • Промене конфигурације уређаја, као што је ротација, доводе до тога да се активност уништава и поново креира као да је нова.
  • Део стања активности је сачуван при промени конфигурације, укључујући тренутне вредности елемената ЕдитТект. За све остале податке морате сами експлицитно да сачувате те податке.
  • Сачувај стање инстанце активности у методи онСавеИнстанцеСтате().
  • Подаци о стању инстанце се чувају као једноставни парови кључ/вредност у скупу. Користите методе Бундле да бисте ставили податке у Бундле и вратили их из Бундле-а.
  • Вратите стање инстанце у онЦреате(), што је преферирани начин, или онРестореИнстанцеСтате(). Назад
,

1. Добродошли

Ова практична лабораторија кода је део јединице 1: Започните на курсу Андроид Девелопер Фундаменталс (верзија 2). Добићете највећу вредност од овог курса ако радите кроз лабораторије кодова у низу:

  • За комплетну листу кодних лабораторија у оквиру курса, погледајте Цоделабс фор Андроид Девелопер Фундаменталс (В2).
  • За детаље о курсу, укључујући везе ка свим поглављима концепта, апликацијама и слајдовима, погледајте Основе Андроид програмера (верзија 2).

Увод

У овој пракси сазнаћете више о животном циклусу активности. Животни циклус је скуп стања у којима активност може да буде током читавог свог животног века, од тренутка када је створена до тренутка када је уништена и када систем поврати своје ресурсе. Док се корисник креће између активности у вашој апликацији (као и у вашу апликацију и ван ње), активности прелазе између различитих стања у свом животном циклусу.

Двострука невоља

Свака фаза у животном циклусу активности има одговарајући метод повратног позива: онЦреате(), онСтарт(), онПаусе(), итд. Када активност промени стање, позива се придружени метод повратног позива. Већ сте видели један од ових метода: онЦреате(). Поништавањем било које методе повратног позива животног циклуса у вашим класама активности, можете променити подразумевано понашање активности као одговор на радње корисника или система.

Стање активности се такође може променити као одговор на промене у конфигурацији уређаја, на пример када корисник ротира уређај из усправног у пејзаж. Када се догоде ове промене конфигурације, активност се уништава и поново креира у свом подразумеваном стању, а корисник може да изгуби информације које је унео у активност. Да не бисте збунили кориснике, важно је да развијете своју апликацију како бисте спречили неочекивани губитак података. Касније у овој пракси експериментишете са променама конфигурације и научите како да сачувате стање активности као одговор на промене конфигурације уређаја и друге догађаје животног циклуса активности.

У овој пракси додајете изјаве за евидентирање у апликацију ТвоАцтивитиес и посматрате промене животног циклуса активности док користите апликацију. Затим почињете да радите са овим променама и да истражујете како да рукујете уносом корисника у овим условима.

Предуслови

Требало би да будете у могућности да:

  • Креирајте и покрените пројекат апликације у Андроид Студију .
  • Додајте изјаве дневника у своју апликацију и прегледајте те евиденције у окну Логцат.
  • Разумети активност и намеру и радити са њима и бити пријатни у интеракцији са њима.

Шта ћете научити

  • Како функционише животни циклус активности.
  • Када се активност покрене, паузира, зауставља и уништава.
  • О методама повратног позива животног циклуса повезаних са променама активности.
  • Ефекат радњи (као што су промене конфигурације) које могу довести до догађаја животног циклуса активности.
  • Како задржати стање активности током догађаја животног циклуса.

Шта ћеш урадити

  • Додајте код у апликацију ТвоАцтивитиес из претходне практичне да бисте имплементирали различите повратне позиве животног циклуса активности да бисте укључили изјаве за евидентирање.
  • Посматрајте промене стања док се апликација покреће и док остварујете интеракцију са сваком активношћу у апликацији.
  • Измените своју апликацију да задржите стање инстанце активности која се неочекивано поново креира као одговор на понашање корисника или промену конфигурације на уређају.

2. Преглед апликације

У овој пракси додајете у апликацију ТвоАцтивитиес . Апликација изгледа и понаша се отприлике исто као у прошлој лабораторији кодова. Садржи две имплементације активности и даје кориснику могућност да шаље између њих. Промене које унесете у апликацију у овој пракси неће утицати на њено видљиво понашање корисника.

3. 3. Задатак 1: Додајте повратне позиве животног циклуса у ТвоАцтивитиес

У овом задатку ћете имплементирати све методе повратног позива животног циклуса активности за штампање порука у логцат када се те методе позову. Ове поруке дневника ће вам омогућити да видите када животни циклус активности мења стање и како те промене стања животног циклуса утичу на вашу апликацију док она ради.

1.1 (Опционо) Копирајте пројекат ТвоАцтивитиес

За задатке у овој пракси, модификоваћете постојећи ТвоАцтивитиес пројекат који сте изградили у последњој пракси. Ако желите да претходни ТвоАцтивитиес пројекат остане нетакнут, пратите кораке у Додатку: Услужни програми да бисте направили копију пројекта.

1.2 Имплементирајте повратне позиве у МаинАцтивити

  1. Отворите пројекат ТвоАцтивитиес у Андроид студију и отворите МаинАцтивити у окну Пројецт > Андроид.
  2. У методу онЦреате() додајте следеће изјаве дневника:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
  1. Додајте замена за онСтарт() повратни позив, са наредбом у дневник за тај догађај:
@Override
public void onStart(){
    super.onStart();
    Log.d(LOG_TAG, "onStart");
}

За пречицу изаберите Цоде > Оверриде Метходс у Андроид Студију. Појављује се дијалог са свим могућим методама које можете заменити у својој класи. Одабиром једне или више метода повратног позива са листе убацује се комплетан шаблон за те методе, укључујући и потребан позив суперкласи.

  1. Користите онСтарт() метод као шаблон за имплементацију повратних позива животног циклуса онПаусе(), онРестарт(), онРесуме(), онСтоп() и онДестрои()

Све методе повратног позива имају исте потписе (осим имена). Ако копирате и налепите онСтарт() да бисте креирали ове друге методе повратног позива, не заборавите да ажурирате садржај да бисте позвали прави метод у суперкласи и да бисте евидентирали исправан метод.

  1. Покрените своју апликацију.
  2. Кликните на картицу Логцат на дну Андроид Студија да бисте приказали окно Логцат. Требало би да видите три дневник поруке које приказују три стања животног циклуса кроз која је активност прешла на почетку:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume

1.3 Имплементирајте повратне позиве животног циклуса у СецондАцтивити

Сада када сте имплементирали методе повратног позива животног циклуса за МаинАцтивити, урадите исто за СецондАцтивити.

  1. Отворите СецондАцтивити.
  2. На врх класе додајте константу за променљиву ЛОГ_ТАГ:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
  1. Додајте повратне позиве животног циклуса и изјаве дневника у другу активност. (Можете да копирате и налепите методе повратног позива из МаинАцтивити.)
  2. Додајте исказ дневника методи ретурнРепли() непосредно пре методе финисх():
Log.d(LOG_TAG, "End SecondActivity");

1.4 Посматрајте евиденцију док апликација ради**

  1. Покрените своју апликацију.
  2. Кликните на картицу Логцат на дну Андроид Студија да бисте приказали окно Логцат.
  3. Унесите Активност у поље за претрагу. Андроид логцат може бити веома дугачак и претрпан. Пошто променљива ЛОГ_ТАГ у свакој класи садржи речи МаинАцтивити или СецондАцтивити, ова кључна реч вам омогућава да филтрирате евиденцију само за оно што вас занима.

Двострука невоља

Експериментишите користећи своју апликацију и запазите да се догађаји животног циклуса дешавају као одговор на различите радње. Конкретно, пробајте ове ствари:

  • Користите апликацију нормално (пошаљите поруку, одговорите другом поруком).
  • Користите дугме Назад да бисте се вратили са друге активности на главну активност.
  • Користите стрелицу нагоре на траци апликација да бисте се вратили са друге активности на главну активност.
  • Ротирајте уређај на главној и другој активности у различито време у апликацији и посматрајте шта се дешава у * евиденцији и на екрану.
  • Притисните дугме за преглед (квадратно дугме десно од Хоме) и затворите апликацију (додирните Кс).
  • Вратите се на почетни екран и поново покрените апликацију.

САВЕТ: Ако своју апликацију покрећете у емулатору, можете симулирати ротацију помоћу Цонтрол+Ф11 или Цонтрол+Фунцтион+Ф11.

Шифра решења задатка 1

Следећи исечци кода приказују код решења за први задатак.

МаинАцтивити

Следећи исечци кода приказују додат код у МаинАцтивити, али не и целу класу.

Метод онЦреате():

@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);
}

Друге методе животног циклуса:

@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");
}

СецондАцтивити

Следећи исечци кода приказују додат код у СецондАцтивити, али не и целу класу.

На врху класе СецондАцтивити:

private static final String LOG_TAG = SecondActivity.class.getSimpleName();

Метод ретурнРепли():

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();
}

Друге методе животног циклуса:

Исто као за МаинАцтивити, горе.

4. 4. Задатак 2: Сачувајте и вратите стање инстанце активности

У зависности од системских ресурса и понашања корисника, свака активност у вашој апликацији може бити уништена и реконструисана много чешће него што мислите.

Можда сте приметили ово понашање у последњем одељку када сте ротирали уређај или емулатор. Ротирање уређаја је један пример промене конфигурације уређаја. Иако је ротација најчешћа, све промене конфигурације доводе до тога да се тренутна активност уништава и поново креира као да је нова. Ако не узмете у обзир ово понашање у свом коду, када дође до промене конфигурације, изглед ваше активности може да се врати на подразумевани изглед и почетне вредности, а ваши корисници могу да изгубе своје место, своје податке или стање свог напретка у ваша апликација.

Стање сваке активности се чува као скуп парова кључ/вредност у Бундле објекту који се зове стање инстанце активности. Систем чува информације о подразумеваном стању у Бундле стања инстанце непосредно пре него што се активност заустави и прослеђује тај Бундле новој инстанци активности да би се вратила.

Да не бисте изгубили податке у активности када је неочекивано уништена и поново направљена, морате да примените метод онСавеИнстанцеСтате(). Систем позива овај метод за вашу активност (између онПаусе() и онСтоп()) када постоји могућност да се активност уништи и поново креира.

Подаци које сачувате у стању инстанце су специфични само за ову инстанцу ове специфичне активности током тренутне сесије апликације. Када зауставите и поново покренете нову сесију апликације, стање инстанце активности се губи и активност се враћа на подразумевани изглед. Ако треба да сачувате корисничке податке између сесија апликације, користите дељена подешавања или базу података. О оба ова сазнаћете у каснијој пракси.

2.1 Сачувајте стање инстанце активности помоћу онСавеИнстанцеСтате()

Можда сте приметили да ротирање уређаја уопште не утиче на стање друге активности. То је зато што се други изглед и стање активности генеришу из изгледа и намере која га је активирала. Чак и ако је активност поново креирана, намера је и даље ту и подаци у тој намери се и даље користе сваки пут када се позове метод онЦреате() у другој активности.

Поред тога, можете приметити да се у свакој активности сваки текст који сте унели у поруку или одговор ЕдитТект елементи задржавају чак и када се уређај ротира. То је зато што се информације о стању неких елемената приказа у вашем распореду аутоматски чувају током промена конфигурације, а тренутна вредност ЕдитТект-а је један од тих случајева.

Дакле, једино стање активности које вас занима су елементи ТектВиев за заглавље одговора и текст одговора у главној активности. Оба елемента ТектВиев су подразумевано невидљива; појављују се само када пошаљете поруку назад главној активности из друге активности.

У овом задатку додајете код да бисте сачували стање инстанце ова два елемента ТектВиев користећи онСавеИнстанцеСтате().

  1. Отворите МаинАцтивити.
  2. Додајте ову скелетну имплементацију онСавеИнстанцеСтате() у активност или користите Цоде > Оверриде Метходс да бисте уметнули замена скелета.
@Override
public void onSaveInstanceState(Bundle outState) {
          super.onSaveInstanceState(outState);
}
  1. Проверите да ли је заглавље тренутно видљиво, и ако јесте, ставите то стање видљивости у стање Бундле са методом путБоолеан() и кључем „репли_висибле“.
 if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
        outState.putBoolean("reply_visible", true);
    }

Запамтите да су заглавље одговора и текст означени као невидљиви све док не добијете одговор из друге активности. Ако је заглавље видљиво, онда постоје подаци о одговору које треба сачувати. Имајте на уму да нас занима само то стање видљивости — стварни текст заглавља не треба да се чува, јер се тај текст никада не мења.

  1. Унутар те исте провере додајте текст одговора у пакет.
outState.putString("reply_text",mReplyTextView.getText().toString());

Ако је заглавље видљиво, можете претпоставити да је и сама порука одговора такође видљива. Не морате да тестирате нити да сачувате тренутно стање видљивости поруке одговора. Само стварни текст поруке иде у стање Бундле са кључем "репли_тект".

Чувате стање само оних елемената приказа који се могу променити након креирања активности. Остали елементи приказа у вашој апликацији (ЕдитТект, дугме) могу се поново креирати из подразумеваног изгледа у било ком тренутку.

Имајте на уму да ће систем сачувати стање неких елемената приказа, као што је садржај ЕдитТект-а.

2.2 Вратите стање инстанце активности у онЦреате()

Када сачувате стање инстанце активности, такође морате да га вратите када се активност поново креира. Ово можете да урадите или у онЦреате(), или имплементацијом повратног позива онРестореИнстанцеСтате(), који се позива након онСтарт() након што се активност креира.

Већину времена боље место за враћање стања активности је у онЦреате(), како би се осигурало да кориснички интерфејс, укључујући стање, буде доступан што је пре могуће. Понекад је згодно то урадити у онРестореИнстанцеСтате() након што је сва иницијализација обављена или дозволити подкласама да одлуче да ли ће користити вашу подразумевану имплементацију.

  1. У методи онЦреате(), након што се променљиве Виев иницијализују помоћу финдВиевБиИд(), додајте тест да бисте се уверили да саведИнстанцеСтате није нулл.
// 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) {
}

Када се ваша активност креира, систем прослеђује стање Бундле онЦреате() као једини аргумент. Када се први пут позове онЦреате() и ваша апликација се покрене, Бундле је нулл—нема постојећег стања када се апликација први пут покрене. Наредни позиви онЦреате() имају скуп попуњен подацима које сте ускладиштили у онСавеИнстанцеСтате().

  1. Унутар те провере, извадите тренутну видљивост (тачно или нетачно) из Бундле-а помоћу кључа „репли_висибле“.
if (savedInstanceState != null) {
    boolean isVisible = 
                     savedInstanceState.getBoolean("reply_visible");
}
  1. Додајте тест испод те претходне линије за променљиву исВисибле.
if (isVisible) {
}

Ако у пакету стања постоји кључ репли_висибле (и исВисибле је стога истинит), мораћете да вратите стање.

  1. Унутар теста исВисибле, учините заглавље видљивим.
mReplyHeadTextView.setVisibility(View.VISIBLE);
  1. Преузмите текстуални одговор из скупа са кључем „репли_тект“ и подесите ТектВиев одговора да приказује тај низ.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
  1. Учините и одговор ТектВиев видљивим:
mReplyTextView.setVisibility(View.VISIBLE);
  1. Покрените апликацију. Покушајте да ротирате уређај или емулатор да бисте били сигурни да порука одговора (ако постоји) остаје на екрану након што се активност поново креира.

Шифра решења задатка 2

Следећи исечци кода приказују код решења за овај задатак.

МаинАцтивити

Следећи исечци кода приказују додат код у МаинАцтивити, али не и целу класу.

Метод онСавеИнстанцеСтате():

@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());
   }
}

Метод онЦреате():

@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);
       }
   }
}

Комплетан пројекат:

Пројекат Андроид Студио: ТвоАцтивитиесЛифецицле

5. Кодирање

Изазов: Направите једноставну апликацију за листу за куповину са главном активношћу за листу коју корисник прави и другом активношћу за листу уобичајених артикала за куповину.

  • Главна активност треба да садржи листу за прављење, која треба да се састоји од десет празних ТектВиев елемената.
  • Дугме Додај ставку на главној активности покреће другу активност која садржи листу уобичајених артикала за куповину (сир, пиринач, јабуке и тако даље). Користите елементе дугмета за приказ ставки.
  • Избор ставке враћа корисника на главну активност и ажурира празан ТектВиев да би укључио изабрану ставку.

Користите намеру да пренесете информације из једне активности у другу. Уверите се да је тренутно стање листе за куповину сачувано када корисник ротира уређај.

6. Резиме

  • Животни циклус активности је скуп стања кроз које се активност мигрира, почевши од тренутка када је први пут креирана и завршавајући када Андроид систем поврати ресурсе за ту активност.
  • Док се корисник креће од једне активности до друге, унутар и ван ваше апликације, свака активност се креће између стања у животном циклусу активности.
  • Свако стање у животном циклусу активности има одговарајући метод повратног позива који можете заменити у својој класи активности.
  • Методе животног циклуса су онЦреате(), онСтарт(), онПаусе(), онРестарт(), онРесуме(), онСтоп(), онДестрои().
  • Заобилажење методе повратног позива животног циклуса вам омогућава да додате понашање које се дешава када ваша активност пређе у то стање.
  • Можете да додате методе замене скелета својим класама у Андроид Студију помоћу Цоде > Оверриде.
  • Промене конфигурације уређаја, као што је ротација, доводе до тога да се активност уништава и поново креира као да је нова.
  • Део стања активности је сачуван при промени конфигурације, укључујући тренутне вредности елемената ЕдитТект. За све остале податке морате сами експлицитно да сачувате те податке.
  • Сачувај стање инстанце активности у методи онСавеИнстанцеСтате().
  • Подаци о стању инстанце се чувају као једноставни парови кључ/вредност у скупу. Користите методе Бундле да бисте ставили податке у Бундле и вратили их из Бундле-а.
  • Вратите стање инстанце у онЦреате(), што је преферирани начин, или онРестореИнстанцеСтате(). Назад
,

1. Добродошли

Ова практична лабораторија кода је део јединице 1: Започните на курсу Андроид Девелопер Фундаменталс (верзија 2). Добићете највећу вредност од овог курса ако радите кроз лабораторије кодова у низу:

  • За комплетну листу кодних лабораторија у оквиру курса, погледајте Цоделабс фор Андроид Девелопер Фундаменталс (В2).
  • За детаље о курсу, укључујући везе ка свим поглављима концепта, апликацијама и слајдовима, погледајте Основе Андроид програмера (верзија 2).

Увод

У овој пракси сазнаћете више о животном циклусу активности. Животни циклус је скуп стања у којима активност може да буде током читавог свог животног века, од тренутка када је створена до тренутка када је уништена и када систем поврати своје ресурсе. Док се корисник креће између активности у вашој апликацији (као и у вашу апликацију и ван ње), активности прелазе између различитих стања у свом животном циклусу.

Двострука невоља

Свака фаза у животном циклусу активности има одговарајући метод повратног позива: онЦреате(), онСтарт(), онПаусе(), итд. Када активност промени стање, позива се придружени метод повратног позива. Већ сте видели један од ових метода: онЦреате(). Поништавањем било које методе повратног позива животног циклуса у вашим класама активности, можете променити подразумевано понашање активности као одговор на радње корисника или система.

Стање активности се такође може променити као одговор на промене у конфигурацији уређаја, на пример када корисник ротира уређај из усправног у пејзаж. Када се догоде ове промене конфигурације, активност се уништава и поново креира у свом подразумеваном стању, а корисник може да изгуби информације које је унео у активност. Да не бисте збунили кориснике, важно је да развијете своју апликацију како бисте спречили неочекивани губитак података. Касније у овој пракси експериментишете са променама конфигурације и научите како да сачувате стање активности као одговор на промене конфигурације уређаја и друге догађаје животног циклуса активности.

У овој пракси додајете изјаве за евидентирање у апликацију ТвоАцтивитиес и посматрате промене животног циклуса активности док користите апликацију. Затим почињете да радите са овим променама и да истражујете како да рукујете уносом корисника у овим условима.

Предуслови

Требало би да будете у могућности да:

  • Креирајте и покрените пројекат апликације у Андроид Студију .
  • Додајте изјаве дневника у своју апликацију и прегледајте те евиденције у окну Логцат.
  • Разумети активност и намеру и радити са њима и бити пријатни у интеракцији са њима.

Шта ћете научити

  • Како функционише животни циклус активности.
  • Када се активност покрене, паузира, зауставља и уништава.
  • О методама повратног позива животног циклуса повезаних са променама активности.
  • Ефекат радњи (као што су промене конфигурације) које могу довести до догађаја животног циклуса активности.
  • Како задржати стање активности током догађаја животног циклуса.

Шта ћеш урадити

  • Додајте код у апликацију ТвоАцтивитиес из претходне практичне да бисте имплементирали различите повратне позиве животног циклуса активности да бисте укључили изјаве за евидентирање.
  • Посматрајте промене стања док се апликација покреће и док остварујете интеракцију са сваком активношћу у апликацији.
  • Измените своју апликацију да задржите стање инстанце активности која се неочекивано поново креира као одговор на понашање корисника или промену конфигурације на уређају.

2. Преглед апликације

У овој пракси додајете у апликацију ТвоАцтивитиес . Апликација изгледа и понаша се отприлике исто као у прошлој лабораторији кодова. Садржи две имплементације активности и даје кориснику могућност да шаље између њих. Промене које унесете у апликацију у овој пракси неће утицати на њено видљиво понашање корисника.

3. 3. Задатак 1: Додајте повратне позиве животног циклуса у ТвоАцтивитиес

У овом задатку ћете имплементирати све методе повратног позива животног циклуса активности за штампање порука у логцат када се те методе позову. Ове поруке дневника ће вам омогућити да видите када животни циклус активности мења стање и како те промене стања животног циклуса утичу на вашу апликацију док она ради.

1.1 (Опционо) Копирајте пројекат ТвоАцтивитиес

За задатке у овој пракси, модификоваћете постојећи ТвоАцтивитиес пројекат који сте изградили у последњој пракси. Ако желите да претходни ТвоАцтивитиес пројекат остане нетакнут, пратите кораке у Додатку: Услужни програми да бисте направили копију пројекта.

1.2 Имплементирајте повратне позиве у МаинАцтивити

  1. Отворите пројекат ТвоАцтивитиес у Андроид студију и отворите МаинАцтивити у окну Пројецт > Андроид.
  2. У методу онЦреате() додајте следеће изјаве дневника:
Log.d(LOG_TAG, "-------");
Log.d(LOG_TAG, "onCreate");
  1. Додајте замена за онСтарт() повратни позив, са наредбом у дневник за тај догађај:
@Override
public void onStart(){
    super.onStart();
    Log.d(LOG_TAG, "onStart");
}

За пречицу изаберите Цоде > Оверриде Метходс у Андроид Студију. Појављује се дијалог са свим могућим методама које можете заменити у својој класи. Одабиром једне или више метода повратног позива са листе убацује се комплетан шаблон за те методе, укључујући и потребан позив суперкласи.

  1. Користите онСтарт() метод као шаблон за имплементацију повратних позива животног циклуса онПаусе(), онРестарт(), онРесуме(), онСтоп() и онДестрои()

Све методе повратног позива имају исте потписе (осим имена). Ако копирате и налепите онСтарт() да бисте креирали ове друге методе повратног позива, не заборавите да ажурирате садржај да бисте позвали прави метод у суперкласи и да бисте евидентирали исправан метод.

  1. Покрените своју апликацију.
  2. Кликните на картицу Логцат на дну Андроид Студија да бисте приказали окно Логцат. Требало би да видите три дневник поруке које приказују три стања животног циклуса кроз која је активност прешла на почетку:
D/MainActivity: -------
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onResume

1.3 Имплементирајте повратне позиве животног циклуса у СецондАцтивити

Сада када сте имплементирали методе повратног позива животног циклуса за МаинАцтивити, урадите исто за СецондАцтивити.

  1. Отворите СецондАцтивити.
  2. На врх класе додајте константу за променљиву ЛОГ_ТАГ:
private static final String LOG_TAG = SecondActivity.class.getSimpleName();
  1. Додајте повратне позиве животног циклуса и изјаве дневника у другу активност. (Можете да копирате и налепите методе повратног позива из МаинАцтивити.)
  2. Додајте исказ дневника методи ретурнРепли() непосредно пре методе финисх():
Log.d(LOG_TAG, "End SecondActivity");

1.4 Посматрајте евиденцију док апликација ради**

  1. Покрените своју апликацију.
  2. Кликните на картицу Логцат на дну Андроид Студија да бисте приказали окно Логцат.
  3. Унесите Активност у поље за претрагу. Андроид логцат може бити веома дугачак и претрпан. Пошто променљива ЛОГ_ТАГ у свакој класи садржи речи МаинАцтивити или СецондАцтивити, ова кључна реч вам омогућава да филтрирате евиденцију само за оно што вас занима.

Двострука невоља

Експериментишите користећи своју апликацију и запазите да се догађаји животног циклуса дешавају као одговор на различите радње. Конкретно, пробајте ове ствари:

  • Користите апликацију нормално (пошаљите поруку, одговорите другом поруком).
  • Користите дугме Назад да бисте се вратили са друге активности на главну активност.
  • Користите стрелицу нагоре на траци апликација да бисте се вратили са друге активности на главну активност.
  • Ротирајте уређај на главној и другој активности у различито време у апликацији и посматрајте шта се дешава у * евиденцији и на екрану.
  • Притисните дугме за преглед (квадратно дугме десно од Хоме) и затворите апликацију (додирните Кс).
  • Вратите се на почетни екран и поново покрените апликацију.

САВЕТ: Ако своју апликацију покрећете у емулатору, можете симулирати ротацију помоћу Цонтрол+Ф11 или Цонтрол+Фунцтион+Ф11.

Шифра решења задатка 1

Следећи исечци кода приказују код решења за први задатак.

МаинАцтивити

Следећи исечци кода приказују додат код у МаинАцтивити, али не и целу класу.

Метод онЦреате():

@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);
}

Друге методе животног циклуса:

@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");
}

СецондАцтивити

Следећи исечци кода приказују додат код у СецондАцтивити, али не и целу класу.

На врху класе СецондАцтивити:

private static final String LOG_TAG = SecondActivity.class.getSimpleName();

Метод ретурнРепли():

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();
}

Друге методе животног циклуса:

Исто као за МаинАцтивити, горе.

4. 4. Задатак 2: Сачувајте и вратите стање инстанце активности

У зависности од системских ресурса и понашања корисника, свака активност у вашој апликацији може бити уништена и реконструисана много чешће него што мислите.

Можда сте приметили ово понашање у последњем одељку када сте ротирали уређај или емулатор. Ротирање уређаја је један пример промене конфигурације уређаја. Иако је ротација најчешћа, све промене конфигурације доводе до тога да се тренутна активност уништава и поново креира као да је нова. Ако не узмете у обзир ово понашање у свом коду, када дође до промене конфигурације, изглед ваше активности може да се врати на подразумевани изглед и почетне вредности, а ваши корисници могу да изгубе своје место, своје податке или стање свог напретка у ваша апликација.

Стање сваке активности се чува као скуп парова кључ/вредност у Бундле објекту који се зове стање инстанце активности. Систем чува информације о подразумеваном стању у Бундле стања инстанце непосредно пре него што се активност заустави и прослеђује тај Бундле новој инстанци активности да би се вратила.

Да не бисте изгубили податке у активности када је неочекивано уништена и поново направљена, морате да примените метод онСавеИнстанцеСтате(). Систем позива овај метод за вашу активност (између онПаусе() и онСтоп()) када постоји могућност да се активност уништи и поново креира.

Подаци које сачувате у стању инстанце су специфични само за ову инстанцу ове специфичне активности током тренутне сесије апликације. Када зауставите и поново покренете нову сесију апликације, стање инстанце активности се губи и активност се враћа на подразумевани изглед. Ако треба да сачувате корисничке податке између сесија апликације, користите дељена подешавања или базу података. О оба ова сазнаћете у каснијој пракси.

2.1 Сачувајте стање инстанце активности помоћу онСавеИнстанцеСтате()

Можда сте приметили да ротирање уређаја уопште не утиче на стање друге активности. То је зато што се други изглед и стање активности генеришу из изгледа и намере која га је активирала. Чак и ако је активност поново креирана, намера је и даље ту и подаци у тој намери се и даље користе сваки пут када се позове метод онЦреате() у другој активности.

Поред тога, можете приметити да се у свакој активности сваки текст који сте унели у поруку или одговор ЕдитТект елементи задржавају чак и када се уређај ротира. То је зато што се информације о стању неких елемената приказа у вашем распореду аутоматски чувају током промена конфигурације, а тренутна вредност ЕдитТект-а је један од тих случајева.

Дакле, једино стање активности које вас занима су елементи ТектВиев за заглавље одговора и текст одговора у главној активности. Оба елемента ТектВиев су подразумевано невидљива; појављују се само када пошаљете поруку назад главној активности из друге активности.

У овом задатку додајете код да бисте сачували стање инстанце ова два елемента ТектВиев користећи онСавеИнстанцеСтате().

  1. Отворите МаинАцтивити.
  2. Додајте ову скелетну имплементацију онСавеИнстанцеСтате() у активност или користите Цоде > Оверриде Метходс да бисте уметнули замена скелета.
@Override
public void onSaveInstanceState(Bundle outState) {
          super.onSaveInstanceState(outState);
}
  1. Проверите да ли је заглавље тренутно видљиво, и ако јесте, ставите то стање видљивости у стање Бундле са методом путБоолеан() и кључем „репли_висибле“.
 if (mReplyHeadTextView.getVisibility() == View.VISIBLE) {
        outState.putBoolean("reply_visible", true);
    }

Запамтите да су заглавље одговора и текст означени као невидљиви све док не добијете одговор из друге активности. Ако је заглавље видљиво, онда постоје подаци о одговору које треба сачувати. Имајте на уму да нас занима само то стање видљивости — стварни текст заглавља не треба да се чува, јер се тај текст никада не мења.

  1. Унутар те исте провере додајте текст одговора у пакет.
outState.putString("reply_text",mReplyTextView.getText().toString());

Ако је заглавље видљиво, можете претпоставити да је и сама порука одговора такође видљива. Не морате да тестирате нити да сачувате тренутно стање видљивости поруке одговора. Само стварни текст поруке иде у стање Бундле са кључем "репли_тект".

Чувате стање само оних елемената приказа који се могу променити након креирања активности. Остали елементи приказа у вашој апликацији (ЕдитТект, дугме) могу се поново креирати из подразумеваног изгледа у било ком тренутку.

Имајте на уму да ће систем сачувати стање неких елемената приказа, као што је садржај ЕдитТект-а.

2.2 Вратите стање инстанце активности у онЦреате()

Када сачувате стање инстанце активности, такође морате да га вратите када се активност поново креира. Ово можете да урадите или у онЦреате(), или имплементацијом повратног позива онРестореИнстанцеСтате(), који се позива након онСтарт() након што се активност креира.

Већину времена боље место за враћање стања активности је у онЦреате(), како би се осигурало да кориснички интерфејс, укључујући стање, буде доступан што је пре могуће. Понекад је згодно то урадити у онРестореИнстанцеСтате() након што је сва иницијализација обављена или дозволити подкласама да одлуче да ли ће користити вашу подразумевану имплементацију.

  1. У методи онЦреате(), након што се променљиве Виев иницијализују помоћу финдВиевБиИд(), додајте тест да бисте се уверили да саведИнстанцеСтате није нулл.
// 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) {
}

Када се ваша активност креира, систем прослеђује стање Бундле онЦреате() као једини аргумент. Када се први пут позове онЦреате() и ваша апликација се покрене, Бундле је нулл—нема постојећег стања када се апликација први пут покрене. Наредни позиви онЦреате() имају скуп попуњен подацима које сте ускладиштили у онСавеИнстанцеСтате().

  1. Унутар те провере, извадите тренутну видљивост (тачно или нетачно) из Бундле-а помоћу кључа „репли_висибле“.
if (savedInstanceState != null) {
    boolean isVisible = 
                     savedInstanceState.getBoolean("reply_visible");
}
  1. Додајте тест испод те претходне линије за променљиву исВисибле.
if (isVisible) {
}

Ако у пакету стања постоји кључ репли_висибле (и исВисибле је стога истинит), мораћете да вратите стање.

  1. Унутар теста исВисибле, учините заглавље видљивим.
mReplyHeadTextView.setVisibility(View.VISIBLE);
  1. Преузмите текстуални одговор из скупа са кључем „репли_тект“ и подесите ТектВиев одговора да приказује тај низ.
mReplyTextView.setText(savedInstanceState.getString("reply_text"));
  1. Учините и одговор ТектВиев видљивим:
mReplyTextView.setVisibility(View.VISIBLE);
  1. Покрените апликацију. Покушајте да ротирате уређај или емулатор да бисте били сигурни да порука одговора (ако постоји) остаје на екрану након што се активност поново креира.

Шифра решења задатка 2

Следећи исечци кода приказују код решења за овај задатак.

МаинАцтивити

Следећи исечци кода приказују додат код у МаинАцтивити, али не и целу класу.

Метод онСавеИнстанцеСтате():

@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());
   }
}

Метод онЦреате():

@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);
       }
   }
}

Комплетан пројекат:

Пројекат Андроид Студио: ТвоАцтивитиесЛифецицле

5. Кодирање

Изазов: Направите једноставну апликацију за листу за куповину са главном активношћу за листу коју корисник прави и другом активношћу за листу уобичајених артикала за куповину.

  • Главна активност треба да садржи листу за прављење, која треба да се састоји од десет празних ТектВиев елемената.
  • Дугме Додај ставку на главној активности покреће другу активност која садржи листу уобичајених артикала за куповину (сир, пиринач, јабуке и тако даље). Користите елементе дугмета за приказ ставки.
  • Избор ставке враћа корисника на главну активност и ажурира празан ТектВиев да би укључио изабрану ставку.

Користите намеру да пренесете информације из једне активности у другу. Уверите се да је тренутно стање листе за куповину сачувано када корисник ротира уређај.

6. Резиме

  • Животни циклус активности је скуп стања кроз које се активност мигрира, почевши од тренутка када је први пут креирана и завршавајући када Андроид систем поврати ресурсе за ту активност.
  • Док се корисник креће од једне активности до друге, унутар и ван ваше апликације, свака активност се креће између стања у животном циклусу активности.
  • Свако стање у животном циклусу активности има одговарајући метод повратног позива који можете заменити у својој класи активности.
  • Методе животног циклуса су онЦреате(), онСтарт(), онПаусе(), онРестарт(), онРесуме(), онСтоп(), онДестрои().
  • Заобилажење методе повратног позива животног циклуса вам омогућава да додате понашање које се дешава када ваша активност пређе у то стање.
  • Можете да додате методе замене скелета својим класама у Андроид Студију помоћу Цоде > Оверриде.
  • Промене конфигурације уређаја, као што је ротација, доводе до тога да се активност уништава и поново креира као да је нова.
  • Део стања активности је сачуван при промени конфигурације, укључујући тренутне вредности елемената ЕдитТект. За све остале податке морате сами експлицитно да сачувате те податке.
  • Сачувај стање инстанце активности у методи онСавеИнстанцеСтате().
  • Подаци о стању инстанце се чувају као једноставни парови кључ/вредност у скупу. Користите методе Бундле да бисте ставили податке у Бундле и вратили их из Бундле-а.
  • Вратите стање инстанце у онЦреате(), што је преферирани начин, или онРестореИнстанцеСтате(). Назад