Страницы

Поиск по вопросам

Показаны сообщения с ярлыком activity-life-cycle. Показать все сообщения
Показаны сообщения с ярлыком activity-life-cycle. Показать все сообщения

суббота, 4 января 2020 г.

Как отличить событие закрытия Activity от поворота экрана?

#java #android #activity #activity_life_cycle


Как программно отличить событие настоящего закрытия Activity от промежуточных вызовов
onStop() и onDestroy() при повороте экрана (изменения ориентации экрана)?
    


Ответы

Ответ 1



Метод boolean isFinishing(). Вызывается обычно в onPause().

среда, 1 января 2020 г.

объект Bundle равен null в onCreate()

#java #android #activity #activity_life_cycle #onsaveinstancestate


Я сохраняю состояние активити в onSaveInstanceState().

Если открыть список недавних приложений и закрыть моё, а потом запустить, в onCreate()
передается null; а если не закрывать, а просто открыть другое приложение, а потом вернуться,
onCreate() не вызовется.
onRestoreInstanceState() не вызывается никогда.

UPD
Как сохранить данные при закрытии приложения, чтобы когда пользователь откроет его
потом, он увидел старое состояние активити?
    


Ответы

Ответ 1



Должно быть вы новичок в Android, но все мы с чего-то начинаем. Вам не хватает знаний о жизненном цикле активности. Подробнее можете прочитать здесь: http://developer.alexanderklimov.ru/android/theory/lifecycle.php Касательно ваших вопросов: метод protected void onCreate(Bundle savedInstanceState) вызывается при создании активности. Активность создается когда мы впервые её открываем или же когда меняем ориентацию с вертикальной на горизонтальную и наоборот. В первом случае savedInstance = null, потому что в нём нет информации и появиться неоткуда. Второй вариант интереснее. При повороте устройства старая активность уничтожается, но перед своим исчезновением успевает вызвать protected void onSaveInstanceState(Bundle outState). Значение outState передается в качестве аргумента в новую активность в метод onCreate(Bundle savedInstanceState). Если вы явно не укажете какие параметры нужно передать в новую активность, то Bundle savedInstanceState будет равен null. Разберём настоящее приложение. Для этого нам поможет инструмент LogCat. В методах onCreate, onSavedInstance, и onDestroy выведем в LogCat информацию, что именно этот метод был вызван. Пр-р: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i("myTag", "call onCreate()"); if (savedInstanceState == null){ Log.i("myTag", "saveInstanceState == null"); } else { Log.i("myTag", "saveInstanceState != null"); } } @Override protected void onDestroy() { Log.i("myTag", "call onDestroy"); super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { Log.i("myTag", "call onSaveInstanceState"); outState.putString("i", "j"); super.onSaveInstanceState(outState); } Пояснения к картинке Строка 1. Мы заходим в приложение и тем самым запускаем главную активность. В этот момент запускается метод onCreate(Bundle savedInstanceState). Строка 2. В методе onCreate(Bundle savedInstanceState) мы сравниваем Bundle savedInstanceState с null. Соответствующую запись выводим в LogCat. Строка 3. Мы меняем ориентацию экрана устройства. (переворачиваем из вертикального положения в горизонтальное или наоборот). Вызывается метод onSaveInstanceState(Bundle outState). Для того, чтобы Bundle outState не был пустым я предварительно в методе onSaveInstanceState(Bundle outState) добавил строку outState.putString("keyForString", "The string I want to save.");. Строка 4. Активность уничтожается, вызывая метод onDestroy(); Строка 5. Создается новая активность, вызывается метод onCreate(Bundle savedInstanceState). Строка 6. В методе onCreate(Bundle savedInstanceState) мы сравниваем Bundle savedInstanceState с null. Но в методе onSaveInstanceState(Bundle outState) мы добавили свою строку, которая находится в объекте Bundle savedInstanceState. Поэтому мы видим что savedInstanceState != null. Строка 7. Я удовлетворился результатом и нажал кнопку назад. Т.о. мы закрыли текущую активность и видим, что вызвался метод onDestroy(). Идём дальше а если не закрывать, а просто открыть другое приложение, а потом вернуться, onCreate() не вызовется. Верно, метод onCreateне вызовется, вместо него вызовется метод onStart. По ранее указанной ссылке вы наглядно увидите, что после того как вы скрыли приложение вызовется метод onStop, а при возвращении вызовется onStart. Пример из документации: https://developer.android.com/training/basics/activity-lifecycle/recreating.html?hl=ru#SaveState Сохранение состояния операции Когда начинается остановка операции, система вызывает метод onSaveInstanceState(), чтобы операция могла сохранить информацию о состоянии с помощью набора пар "ключ-значение". По умолчанию при реализации этого метода сохраняется информация о состоянии иерархии представления операции, например текст в виджете EditText или положение экрана для ListView. Для сохранения дополнительной информации о состоянии операции необходимо реализовать onSaveInstanceState() и добавить к объекту Bundle пары "ключ-значение". Например: static final String STATE_SCORE = "playerScore"; static final String STATE_LEVEL = "playerLevel"; ... @Override public void onSaveInstanceState(Bundle savedInstanceState) { // Save the user's current game state savedInstanceState.putInt(STATE_SCORE, mCurrentScore); savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); // Always call the superclass so it can save the view hierarchy state super.onSaveInstanceState(savedInstanceState); } Внимание! Реализацию суперкласса onSaveInstanceState() следует вызывать во всех случаях, чтобы реализация по умолчанию могла сохранить состояние новой иерархии. Восстановление состояния операции В случае воссоздания операции после предыдущего уничтожения сохраненное состояние можно восстановить из Bundle, куда система передает данные операции. Методы обратного вызова onCreate() и onRestoreInstanceState() получают один и тот же Bundle, содержащий информацию о состоянии экземпляра. Поскольку метод onCreate() вызывается, если система создает новый экземпляр операции или восстанавливает предыдущий экземпляр, перед попыткой чтения необходимо убедиться, что Bundle имеет состояние null. В этом случае система создает новый экземпляр операции вместо восстановления ранее уничтоженного экземпляра. Приведем пример восстановления некоторых данных о состоянии в onCreate(): @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Always call the superclass first // Check whether we're recreating a previously destroyed instance if (savedInstanceState != null) { // Restore value of members from saved state mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } else { // Probably initialize members with default values for a new instance } ... } Вместо восстановления состояния в onCreate() вы можете реализовать метод onRestoreInstanceState(), который система вызывает после метода onStart(). Система вызывает onRestoreInstanceState() только при наличии сохраненного состояния для восстановления, и поэтому вам не нужно проверять, имеет ли Bundle значение null: public void onRestoreInstanceState(Bundle savedInstanceState) { // Always call the superclass so it can restore the view hierarchy super.onRestoreInstanceState(savedInstanceState); // Restore state members from saved instance mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } Внимание! Реализацию суперкласса onRestoreInstanceState() следует вызывать во всех случаях, чтобы реализация по умолчанию могла сохранить состояние новой иерархии.

вторник, 31 декабря 2019 г.

Существует ли onPause() без onStop()?

#android #activity #activity_life_cycle


В теории жизненного цикла Activity существует переход от onPause() к onResume(),
но ни эксперименты с запуском AlertDialog, ни входящий звонок на телефон во время исполнения
моего Activity, не дают сработки только onPause() без срабатывания onStop().
В какой реальной ситуации на практике происходит срабатывание только onPause() без
срабатывания onStop() и происходит ли вообще?
    


Ответы

Ответ 1



onPause() всегда вызывается (если с логикой программы всё нормально). onStop() может не вызваться, к примеру, если не хватает памяти. Это даже в документации сказано: Это метод может так и не вызваться, в ситуациях, когда не хватает памяти, чтобы продолжить работу вашего Activity после вызова onPause(). Так же метод finish() ломает логику и не позволяет вызваться нужным ивентам. Если вы напишите что-то такое: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); finish(); } @Override protected void onDestroy() { super.onDestroy(); Log.e("MainActivity", "onDestroy"); } @Override protected void onPause() { super.onPause(); Log.e("MainActivity", "onPause"); } @Override protected void onStop() { super.onStop(); Log.e("MainActivity", "onStop"); } То сработает только onDestroy(), а onPause() и onStop() нет.

Ответ 2



Если посмотреть на блок-схему вызова методов жизненного цикла, то можно заметить, что метод onPause() вызывается после ухода активити в фон, а метод onStop() при ее исчезновении с экрана. Соответственно, в штатной работе активити, вызов метода onPause() без вызова метода onStop() возможен, когда активити ушла в фон, но остается видимой на экране, а затем происходит возврат в эту активити. На практике это может быть, к примеру, вызов диалога и возврат из диалога в активити. Про нештатные ситуации уже сказали - при уничтожении активити через GC (например, катастрофическая нехватка памяти) будет вызван только onPause() и активити уничтожена.

воскресенье, 22 декабря 2019 г.

Как запустить рекламу адмоба(видео) при старте приложения?

#java #android #admob #activity_life_cycle


Ссылка на офф. документацию : https://developers.google.com/admob/android/interstitial

Сделал как там все описано - работает, но только при нажатии кнопки. А как сделать,
что бы при каждом запуске приложения отображалась реклама 1 раз? 
    


Ответы

Ответ 1



Надо отследить что пользователь открыл приложение, а не (например) повернул. Это можно сделать проверив if(savedInstanceState==null) это аргумент в onCreate методе активити. После её поворота (пересоздания) этот аргумент уже не null и условие выполнено не будет. В этом условии сформировать запрос к AdMob Запустить его и ждать пока реклама не отобразится. public class MainActivity extends ActionBarActivity { boolean adsAlredyShown = false; InterstitialAd mInterstitialAd; @Override protected void onCreate(Bundle savedInstanceState) { Log.i("LOG", "onCreate"); super.onCreate(savedInstanceState); mInterstitialAd = new InterstitialAd(this); mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712"); //идентификатор из доков надо заменить на свой mInterstitialAd.setAdListener(new AdListener() { @Override public void onAdClosed() { Log.i("LOG", "onAdClosed"); } public void onAdLeftApplication() { Log.i("LOG", "onAdLeftApplication"); } @Override public void onAdLoaded() { Log.i("LOG", "onAdLoaded"); mInterstitialAd.show(); } public void onAdFailedToLoad(int errorCode) { Log.e("LOG", "onAdFailedToLoad with errorCode " + errorCode); } @Override public void onAdOpened() { Log.i("LOG", "onAdOpened"); //вызывается в момент отображения рекламы. //и раз она отобразилась ставим флаг в true //чтобы больше её не показывать adsAlredyShown = true; } }); if(savedInstanceState==null) { AdRequest adRequest = new AdRequest.Builder().build(); mInterstitialAd.loadAd(adRequest); } else { adsAlreadyShown = savedInstanceState.getBoolean("AdsAlreadyShown", false); //реклама ещё не показывалась if(!adsAlreadyShown) { AdRequest adRequest = new AdRequest.Builder().build(); mInterstitialAd.loadAd(adRequest); } } } protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean("AdsAlreadyShown", adsAlreadyShown); } } Также, в тот же savedInstanceState можно поместить флаг после показа рекламы и не показывать её пока он true. Этот флаг исчезнет только если активити будет убита системой или вручную методом finish()

Ответ 2



Дык, по правилам Гугла, рекламу Запрещено отображать при старте приложения ? Недопустимые способы размещения межстраничных объявлений

суббота, 21 декабря 2019 г.

Сохранение элементов ListView после перезагрузки приложения

#java #android #listview #activity_life_cycle


Есть приложение, в котором при нажатии на кнопку создаются и добавляются элементы
списка ListView. При перезагрузке приложения, они пропадают. Догадываюсь, что нужно
использовать БД, и при создании элемента добавлять его в БД, а в методе OnCreate поставить
создание списка ListView из элементов в БД(исправьте, если я не прав). Вопрос такой:
можно ли сохранять список после перезагрузки приложения НЕ ИСПОЛЬЗУЯ БД, т.к. в списке
будет максимум 10-15 элеметов(это потолок). Б
    


Ответы

Ответ 1



У Activity есть onSaveInstanceState, который срабатывает при закрытии. Переопределите его, чтоб сохранить данные из ListView: public void onSaveInstanceState(Bundle savedState) { super.onSaveInstanceState(savedState); // здесь берём данные из адаптера // если у вас ArrayAdapter, то будет так String[] values = mAdapter.getValues(); savedState.putStringArray("myKey", values); } А потом в onCreate получайте: public void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { String[] values = savedInstanceState.getStringArray("myKey"); if (values != null) { mAdaptor = new MyAdaptor(values); } } [...] }

Ответ 2



Можно. Вы можете хранить данные разными способами: В SharedPreferences Записывая данные в свой файл любого формата. Использовать БД Также, если вы под "перезагрузкой приложения" имеете в виду пересоздание экрана при его повороте, то вам также поможет инфа по ссылке из п.1 (сохранение данных активити в Bundle при поворотах экрана)

понедельник, 9 декабря 2019 г.

Сохранение и загрузка состояния Activity

#java #android #activity #activity_life_cycle #android_shared_preferences


Возможно ли в Android сохранить разметку с значениями в файл, чтобы после можно было
её из этого файла потом загрузить?

Допустим, у меня есть main.xml, там 2 Button и 20 TextView. Для каждого TextView
я программно написал текст (каждый текст около 20 слов).

Можно ли как-нибудь сохранить это всё и запустить в новом Activity? Просто такой
же эффект возникает при повороте экрана, эти два метода уже не работают. ((

onRetainNonConfigurationInstance()
getLastNonConfigurationInstance()

    


Ответы

Ответ 1



Если я правильно понял, вам надо куда-то сохранить строки из TextView и восстановить их после поворота активити или передать в другую активити. Для этого есть класс Bundle. В него можно сохранить ваши строки, а потом извлечь. Для сохранения в текущей активити используйте метод onSaveInstanceState(Bundle state) активити: @Override public void onSaveInstanceState(Bundle state) { //находим TextView TextView tV=(TextView )this.findViewById(R.id.yours_text_view_id); String textFromTextViewToSave=tv.getText(); state.putString("str1", textFromTextViewToSave); } Для восстановления этого текста при повороте активити в onCreate пишем @Override public void onCreate(Bundle state) { //находим TextView TextView tV=(TextView )this.findViewById(R.id.yours_text_view_id); String textFromTextViewToSave=state.getString("str1"); tV.setText(textFromTextViewToSave); } Для передачи этих значений в другую активити действуйте по аналогии, сохраняя строки из TextView в Bundle Intent-а, коим запускаете эту активити: Intent intent=new Intent(context, YourAnoterActivity.class); intent.putStringExtra("str1", textFromTextViewToSave); context.startActivity(intent); , а восстанавливая их в OnCreate этой активити так: @Override public void onCreate(Bundle state) { String fromIntent=this.getIntent.getString("str1"); } Ещё можно сохранять в SharePreferences. Так вы не будете зависеть от жизненного цикла. //сохраняем строку в файл внутренней директории приложения SharePreferences pref=PreferenceManager.getDefaultSharedPreferences(context); pref.edit().putString("key", "value").commit(); //получаем ранее сохранённые данные String savedData=pref.getString("key");

воскресенье, 1 декабря 2019 г.

Android/Java. Как отследить событие уничтожения Activity в стеке фоновых приложений?

#android #activity #activity_life_cycle #backstack



запускаю Activity;
нажимаю кнопку Home;
Activity сворачивается в стек фоновых приложений:




Если теперь как бы смахнуть влево/вправо, то Activity закрывается, но событие OnDestroy()
не срабатывает.

Вопрос: как отследить это событие? 

Как при этом вызвать OnDestroy()? Или какой-то другой метод есть (срабатывающий)?
    


Ответы

Ответ 1



При таком сценарии использования ничто не гарантирует вызов onDestroy(). Если Вам необходимо выполнить какие-либо действия при сворачивании программы, пользуйтесь onPause() или onStop (в зависимости от того что необходимо). onDestroy() вызывается при правильном закрытии программы. Вот когда Вы нажимаете кнопку "Назад" на телефоне и приложение "сворачивается", то оно не сворачивается, а закрывается и onDestroy() будет вызван.

среда, 17 апреля 2019 г.

объект Bundle равен null в onCreate()

Я сохраняю состояние активити в onSaveInstanceState()
Если открыть список недавних приложений и закрыть моё, а потом запустить, в onCreate() передается null; а если не закрывать, а просто открыть другое приложение, а потом вернуться, onCreate() не вызовется. onRestoreInstanceState() не вызывается никогда.
UPD Как сохранить данные при закрытии приложения, чтобы когда пользователь откроет его потом, он увидел старое состояние активити?


Ответ

Должно быть вы новичок в Android, но все мы с чего-то начинаем. Вам не хватает знаний о жизненном цикле активности. Подробнее можете прочитать здесь: http://developer.alexanderklimov.ru/android/theory/lifecycle.php
Касательно ваших вопросов:
метод protected void onCreate(Bundle savedInstanceState) вызывается при создании активности. Активность создается когда мы впервые её открываем или же когда меняем ориентацию с вертикальной на горизонтальную и наоборот. В первом случае savedInstance = null, потому что в нём нет информации и появиться неоткуда. Второй вариант интереснее. При повороте устройства старая активность уничтожается, но перед своим исчезновением успевает вызвать protected void onSaveInstanceState(Bundle outState). Значение outState передается в качестве аргумента в новую активность в метод onCreate(Bundle savedInstanceState). Если вы явно не укажете какие параметры нужно передать в новую активность, то Bundle savedInstanceState будет равен null.
Разберём настоящее приложение. Для этого нам поможет инструмент LogCat. В методах onCreate, onSavedInstance, и onDestroy выведем в LogCat информацию, что именно этот метод был вызван. Пр-р:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i("myTag", "call onCreate()"); if (savedInstanceState == null){ Log.i("myTag", "saveInstanceState == null"); } else { Log.i("myTag", "saveInstanceState != null"); } }
@Override protected void onDestroy() { Log.i("myTag", "call onDestroy"); super.onDestroy(); }
@Override protected void onSaveInstanceState(Bundle outState) { Log.i("myTag", "call onSaveInstanceState"); outState.putString("i", "j"); super.onSaveInstanceState(outState); }

Пояснения к картинке
Строка 1. Мы заходим в приложение и тем самым запускаем главную активность. В этот момент запускается метод onCreate(Bundle savedInstanceState).
Строка 2. В методе onCreate(Bundle savedInstanceState) мы сравниваем Bundle savedInstanceState с null. Соответствующую запись выводим в LogCat.
Строка 3. Мы меняем ориентацию экрана устройства. (переворачиваем из вертикального положения в горизонтальное или наоборот). Вызывается метод onSaveInstanceState(Bundle outState). Для того, чтобы Bundle outState не был пустым я предварительно в методе onSaveInstanceState(Bundle outState) добавил строку outState.putString("keyForString", "The string I want to save.");
Строка 4. Активность уничтожается, вызывая метод onDestroy();
Строка 5. Создается новая активность, вызывается метод onCreate(Bundle savedInstanceState).
Строка 6. В методе onCreate(Bundle savedInstanceState) мы сравниваем Bundle savedInstanceState с null. Но в методе onSaveInstanceState(Bundle outState) мы добавили свою строку, которая находится в объекте Bundle savedInstanceState. Поэтому мы видим что savedInstanceState != null
Строка 7. Я удовлетворился результатом и нажал кнопку назад. Т.о. мы закрыли текущую активность и видим, что вызвался метод onDestroy()
Идём дальше
а если не закрывать, а просто открыть другое приложение, а потом вернуться, onCreate() не вызовется.
Верно, метод onCreateне вызовется, вместо него вызовется метод onStart. По ранее указанной ссылке вы наглядно увидите, что после того как вы скрыли приложение вызовется метод onStop, а при возвращении вызовется onStart

Пример из документации:
https://developer.android.com/training/basics/activity-lifecycle/recreating.html?hl=ru#SaveState
Сохранение состояния операции
Когда начинается остановка операции, система вызывает метод onSaveInstanceState(), чтобы операция могла сохранить информацию о состоянии с помощью набора пар "ключ-значение". По умолчанию при реализации этого метода сохраняется информация о состоянии иерархии представления операции, например текст в виджете EditText или положение экрана для ListView. Для сохранения дополнительной информации о состоянии операции необходимо реализовать onSaveInstanceState() и добавить к объекту Bundle пары "ключ-значение". Например:
static final String STATE_SCORE = "playerScore"; static final String STATE_LEVEL = "playerLevel";
...
@Override public void onSaveInstanceState(Bundle savedInstanceState) { // Save the user's current game state savedInstanceState.putInt(STATE_SCORE, mCurrentScore); savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state super.onSaveInstanceState(savedInstanceState); }
Внимание! Реализацию суперкласса onSaveInstanceState() следует вызывать во всех случаях, чтобы реализация по умолчанию могла сохранить состояние новой иерархии.

Восстановление состояния операции
В случае воссоздания операции после предыдущего уничтожения сохраненное состояние можно восстановить из Bundle, куда система передает данные операции. Методы обратного вызова onCreate() и onRestoreInstanceState() получают один и тот же Bundle, содержащий информацию о состоянии экземпляра. Поскольку метод onCreate() вызывается, если система создает новый экземпляр операции или восстанавливает предыдущий экземпляр, перед попыткой чтения необходимо убедиться, что Bundle имеет состояние null. В этом случае система создает новый экземпляр операции вместо восстановления ранее уничтоженного экземпляра. Приведем пример восстановления некоторых данных о состоянии в onCreate():
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance if (savedInstanceState != null) { // Restore value of members from saved state mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } else { // Probably initialize members with default values for a new instance } ... }
Вместо восстановления состояния в onCreate() вы можете реализовать метод onRestoreInstanceState(), который система вызывает после метода onStart(). Система вызывает onRestoreInstanceState() только при наличии сохраненного состояния для восстановления, и поэтому вам не нужно проверять, имеет ли Bundle значение null:
public void onRestoreInstanceState(Bundle savedInstanceState) { // Always call the superclass so it can restore the view hierarchy super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); }
Внимание! Реализацию суперкласса onRestoreInstanceState() следует вызывать во всех случаях, чтобы реализация по умолчанию могла сохранить состояние новой иерархии.

четверг, 31 января 2019 г.

Как отличить событие закрытия Activity от поворота экрана?

Как программно отличить событие настоящего закрытия Activity от промежуточных вызовов onStop() и onDestroy() при повороте экрана (изменения ориентации экрана)?


Ответ

Метод boolean isFinishing(). Вызывается обычно в onPause()

пятница, 16 ноября 2018 г.

Как запустить рекламу адмоба(видео) при старте приложения?

Ссылка на офф. документацию : https://developers.google.com/admob/android/interstitial
Сделал как там все описано - работает, но только при нажатии кнопки. А как сделать, что бы при каждом запуске приложения отображалась реклама 1 раз?


Ответ

Надо отследить что пользователь открыл приложение, а не (например) повернул. Это можно сделать проверив if(savedInstanceState==null) это аргумент в onCreate методе активити. После её поворота (пересоздания) этот аргумент уже не null и условие выполнено не будет. В этом условии сформировать запрос к AdMob Запустить его и ждать пока реклама не отобразится.
public class MainActivity extends ActionBarActivity { boolean adsAlredyShown = false; InterstitialAd mInterstitialAd;
@Override protected void onCreate(Bundle savedInstanceState) { Log.i("LOG", "onCreate"); super.onCreate(savedInstanceState);
mInterstitialAd = new InterstitialAd(this); mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712"); //идентификатор из доков надо заменить на свой mInterstitialAd.setAdListener(new AdListener() { @Override public void onAdClosed() { Log.i("LOG", "onAdClosed"); }
public void onAdLeftApplication() { Log.i("LOG", "onAdLeftApplication"); }
@Override public void onAdLoaded() { Log.i("LOG", "onAdLoaded"); mInterstitialAd.show(); }
public void onAdFailedToLoad(int errorCode) { Log.e("LOG", "onAdFailedToLoad with errorCode " + errorCode); } @Override public void onAdOpened() { Log.i("LOG", "onAdOpened"); //вызывается в момент отображения рекламы. //и раз она отобразилась ставим флаг в true //чтобы больше её не показывать adsAlredyShown = true; } });
if(savedInstanceState==null) { AdRequest adRequest = new AdRequest.Builder().build(); mInterstitialAd.loadAd(adRequest); } else { adsAlreadyShown = savedInstanceState.getBoolean("AdsAlreadyShown", false); //реклама ещё не показывалась if(!adsAlreadyShown) { AdRequest adRequest = new AdRequest.Builder().build(); mInterstitialAd.loadAd(adRequest); } } }
protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean("AdsAlreadyShown", adsAlreadyShown); } }

Также, в тот же savedInstanceState можно поместить флаг после показа рекламы и не показывать её пока он true. Этот флаг исчезнет только если активити будет убита системой или вручную методом finish()

пятница, 9 ноября 2018 г.

Сохранение элементов ListView после перезагрузки приложения

Есть приложение, в котором при нажатии на кнопку создаются и добавляются элементы списка ListView. При перезагрузке приложения, они пропадают. Догадываюсь, что нужно использовать БД, и при создании элемента добавлять его в БД, а в методе OnCreate поставить создание списка ListView из элементов в БД(исправьте, если я не прав). Вопрос такой: можно ли сохранять список после перезагрузки приложения НЕ ИСПОЛЬЗУЯ БД, т.к. в списке будет максимум 10-15 элеметов(это потолок). Б


Ответ

У Activity есть onSaveInstanceState, который срабатывает при закрытии. Переопределите его, чтоб сохранить данные из ListView
public void onSaveInstanceState(Bundle savedState) {
super.onSaveInstanceState(savedState);
// здесь берём данные из адаптера // если у вас ArrayAdapter, то будет так String[] values = mAdapter.getValues(); savedState.putStringArray("myKey", values);
}
А потом в onCreate получайте:
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) { String[] values = savedInstanceState.getStringArray("myKey"); if (values != null) { mAdaptor = new MyAdaptor(values); } }
[...]
}

четверг, 1 ноября 2018 г.

Сохранение и загрузка состояния Activity

Возможно ли в Android сохранить разметку с значениями в файл, чтобы после можно было её из этого файла потом загрузить?
Допустим, у меня есть main.xml, там 2 Button и 20 TextView. Для каждого TextView я программно написал текст (каждый текст около 20 слов).
Можно ли как-нибудь сохранить это всё и запустить в новом Activity? Просто такой же эффект возникает при повороте экрана, эти два метода уже не работают. ((
onRetainNonConfigurationInstance() getLastNonConfigurationInstance()


Ответ

Если я правильно понял, вам надо куда-то сохранить строки из TextView и восстановить их после поворота активити или передать в другую активити. Для этого есть класс Bundle
В него можно сохранить ваши строки, а потом извлечь.
Для сохранения в текущей активити используйте метод onSaveInstanceState(Bundle state) активити:
@Override public void onSaveInstanceState(Bundle state) { //находим TextView TextView tV=(TextView )this.findViewById(R.id.yours_text_view_id); String textFromTextViewToSave=tv.getText(); state.putString("str1", textFromTextViewToSave); } Для восстановления этого текста при повороте активити в onCreate пишем
@Override public void onCreate(Bundle state) { //находим TextView TextView tV=(TextView )this.findViewById(R.id.yours_text_view_id); String textFromTextViewToSave=state.getString("str1"); tV.setText(textFromTextViewToSave); } Для передачи этих значений в другую активити действуйте по аналогии, сохраняя строки из TextView в Bundle Intent-а, коим запускаете эту активити:
Intent intent=new Intent(context, YourAnoterActivity.class); intent.putStringExtra("str1", textFromTextViewToSave); context.startActivity(intent);
, а восстанавливая их в OnCreate этой активити так:
@Override public void onCreate(Bundle state) { String fromIntent=this.getIntent.getString("str1"); } Ещё можно сохранять в SharePreferences. Так вы не будете зависеть от жизненного цикла.
//сохраняем строку в файл внутренней директории приложения SharePreferences pref=PreferenceManager.getDefaultSharedPreferences(context); pref.edit().putString("key", "value").commit();
//получаем ранее сохранённые данные String savedData=pref.getString("key");