19 мая 2014 г.

Работа со временем, часовыми поясами и т.п. в Android и Java

Это заметка чисто для себя, но может кому тоже сгодится. Интересные вещи обнаружил для себя при работе со временем и датами в Андроид

// получаем часовой пояс в милисекундах
Integer msTZ = TimeZone.getDefault().getRawOffset()
+ TimeZone.getTimeZone(TimeZone.getDefault().getID())
.getDSTSavings();

Log.d(TAG,"-----------------------------------");
Log.d(TAG,"TimeZone RowOffset in ms: " + msTZ + " "+ TimeZone.getDefault().getID());
Log.d(TAG,"DSTSavings: "+ TimeZone.getTimeZone(TimeZone.getDefault().getID()).getDSTSavings());
Log.d(TAG,"DisplayName: "+ TimeZone.getTimeZone(TimeZone.getDefault().getID()).getDisplayName());
Log.d(TAG,"GetID_GetID: "+ TimeZone.getTimeZone(TimeZone.getDefault().getID()).getID());
Log.d(TAG,"UseDayLightTime: "+ TimeZone.getTimeZone(TimeZone.getDefault().getID()).useDaylightTime());
// boolean inDay=TimeZone.getTimeZone(TimeZone.getDefault().getID()).inDaylightTime(new Date());
boolean inDay = TimeZone.getTimeZone(TimeZone.getDefault().getID()).inDaylightTime(dateForCalc);
Log.d(TAG,"inDaylightTime: " + inDay);
Log.d(TAG,"GetID: " + TimeZone.getTimeZone(TimeZone.getDefault().getID()));
Log.d(TAG,"INFO-->: "+ TimeZone.getTimeZone(TimeZone.getDefault().getID()));
Log.d(TAG, "TimeZone getDefault()---->: " + TimeZone.getDefault());

16 мая 2014 г.

Задачи и обратный стек (Tasks and back stack). Часть 13 (практика)

Продолжаем разбираться с launchMode="singleInstance". Напомню что в приложении AP0004 Активность Е имеет параметр запуска launchMode="singleInstance".

И так я поправил работу счетчика. И по ходу выяснил еще несколько интересных особенностей работы Активности в этом режиме запуска.

И так запускаем приложение AP0004 и далее последовательно Активности B-C-D

S0001

S0002

S0003

S0004

В задаче 147 сейчас ЧЕТЫРЕ Активности и стек задачи имеет вид A-B-C-D.

Жмем Start Activity E

S0005

Тут тоже все обычно, все как и положено, Активность Е запустилась в новой задаче 148.

Введем текст в поле и нажмем Start Activity A.

S0006

S0007

Активность А запустилась в задаче 147, то есть в задаче приложения AP0004, которое мы запустили в начале. На это тоже следует обратить внимание. Сейчас в задаче 147 ПЯТЬ Активностей и стек имеет вид A-B-C-D-A.

Если нажать кнопку обратно, то как вы помните мы уже не попадем в Активность Е, из которой была запущена текущая Активность А, а попадем в Активность D, поскольку Активность Е не находится в стеке Активностей задачи 147.

На всякий случай для пущего понимания нажмем кнопку Info и глянем лог

S0008

Теперь нажмем кнопку ОБРАТНО

S0009

Мы вернулись в Активность D, которая сообщила нам что она уже была запущена и что сейчас в нашей задаче 147 ЧЕТЫРЕ Активности и стек имеет вид A-B-C-D.

Жмем три раза кнопку ОБРАТНО

S0010

S0011

S0012

И теперь если в Активности А мы нажмем кнопку обратно, то попадем в Активность Е. Это происходит только при условии что мы ни когда, не нажимали кнопку HOME, которая меняет порядок задач, переключаясь на задачу домашнего экрана. Жмем ОБРАТНО

S0013

Видим нашу Активность Е которая находится в таске 148. Если сейчас нажмем еще раз ОБРАТНО, то полностью выйдем из всех Активностей приложения AP0004. Что мы и сделаем.
Затем снова запустим приложение AP0004, чтобы продемонстрировать еще раз, что происходит при нажатии кнопки HOME, когда Активность Е уже запущена.

Запускаем AP0004 и последовательно запускаем активности B-C-D (Активность А у нас запускается при старте приложения, это я так для тех кто в таке).

S0014

S0015

S0016

S0017

Все как обычно, просто таск уже другой. Теперь запустим Активность Е и введем в нее любой текст

S0018

Активность Е запустилась в новом таске с ID=150. Теперь нажмем кнопку HOME

S0019

И снова запустим приложение AP0004. Можно ожидать что мы попадем в Активность Е, но не тут то было! Запускаем AP0004

S0020

И попадаем в таск 149, то есть в таск приложения AP0004. В Активность Е мы не попали, потому что, хотя она и работает в процессе приложения AP0004, но работает в своей задаче.
Теперь чтобы попасть в Активность Е, нам надо будет нажать снова Start Activity E

S0021

Она нам сообщает что уже была запущена, что собственно правда. Теперь жмем пять раз ОБРАТНО и выходим из приложения AP0004.

Задачи и обратный стек (Tasks and back stack). Часть 12 (практика)

Таки переходим к launchMode="singleInstance". Улыбка

В приложении АР0004 для Активность Е launchMode определен как "singleInstance".

В приложении AP0004 есть пять Активностей A, B, C, D, E, в каждой из которых есть кнопка запуска следующей Активности. Активность Е имеет кнопку запуска Активности А из приложения AP0004. То есть по существу создан запуск Активностей по кругу.

Запускаем приложение AP004 и последовательно запускаем Активности В, С и D

SI0001

SI0002

SI0003

SI0004

Здесь все как обычно. Стоит только запомнить что в задаче TaskID=13 сейчас ЧЕТЫРЕ Активности, а стек задачи имеет вид A-B-C-D. Теперь нажимаем Start Activity E

SI0005

Замечаем, что Активность Е была запущена уже в другой задаче с TaskID=14. Посмотрим логи

SI0006

В логах видно, что Активность Е была запущена в новой задаче и запущена как мы помним из Активности D, это тоже надо запомнить. Так же стоит отметить, что Активность Е, как и должно тому быть, была запущена в процессе своего приложения, в данном случае 1618.

Нажмем кнопку Info и посмотрим логи

SI0007

И так замечаем, что в задаче 13 у нас по прежнему ЧЕТЫРЕ Активности и стек задачи имеет вид A-B-C-D. В задаче же 14 только одна Активность Е и она там всегда будет единственной, так как у нее launchMode="singleInstance".

Теперь нажмем кнопку Start Activity A и запомним что Активность А мы запустили из Активности Е.

SI0008

Замечаем, что Активность А, у нас так же была запущена в задаче 13, в которой теперь ПЯТЬ Активностей и стек имеет вид A-B-C-D-A. Нажмем кнопку Info и посмотрим логи

SI0009

Собственно из логов все это видно. Теперь еще раз вспомним что Активность А мы запустили из Активности Е. Нажмем кнопку ОБРАТНО и посмотрим что будет.

SI0010

Мы вернулись а Активность D в задачу 13! Хотя Активность А была запущена из Активности Е, возврат произошел в Активность D, поскольку Активность E была запущена в отдельной задаче. То есть возврата в Активность Е не произошло. Счетчик в этот раз тоже сработал не правильно. Будет время и желание пофиксю и это. Но сейчас в задаче 13 ЧЕТЫРЕ Активности и стек задачи имеет вид A-B-C-D. Нажмем кнопку Info, чтобы убедится в этом

SI0011

Зеленым отмечена задача 13. Как видно там четыре Активности. В задаче 14 одна Активность Е. В желтой рамке виден переход из Активности А в Активность D. Если сейчас нажать кнопку HOME и снова вернуться в приложение AP0004, то Активность D уже отобразить правильное количество Активностей в задаче 13.

SI0012

Этот глюк счетчика в Активности если будет время пофиксю. А сейчас идем дальше. Нажимаем кнопку ОБРАТНО три раза

SI0013

SI0014

SI0015

Замечаем, что все Активности нам сообщают что они были уже запущены. Теперь на данном этапе в задаче 13 у нас одна Активность А. И в задаче 14 тоже одна Активность Е. Нажмем Info чтобы убедится

SI0016

Логи это подтвердили. Теперь вопрос, задача 14 существует, как в нее попасть? По идее если сейчас в Активности А нажать ОБРАТНО, то мы должны выйти из приложения АР0004, так как Активность А, у нас сейчас единственная и последняя в стеке задачи 13. Сделаем это. Жмем кнопку ОБРАТНО

SI0017

И выходим из приложеня Печальная рожица А как же теперь попасть в задачу 14?

Запускаем AP0004 заново

SI0018

Видим что она уже запущена в задаче 16. Жмем Info

SI0019

Мы видим, что задача 14 по прежнему существует и в ней есть Активность Е! Как до нее добраться? Запускаем заново Активности B-C-D

SI0020

SI0021

SI0022

Сейчас стек задачи 16 имеет вид A-B-C-D. То есть в нем ЧЕТЫРЕ Активности. Жмем кнопку Start Activity E.

SI0023

Активность Е нам честно сообщает что она уже была запущена прежде, что мы и так знаем. И задача 14 продолжала болтаться в памяти, хотя мы вышли из приложения AP0004.

Введем текст в текстовом поле

SI0024

Нажмем Start Activity A

SI0025

Теперь в задаче 15 у нас 5 Активностей. Собственно сейчас все повторяется как было до этого. Нажмем кнопку ОБРАТНО

SI0026

Счетчик опять глюканул, так как я его не правил еще. Жмем опять ОБРАТНО

SI0027

Здесь уже со счетчиком все нормально. Жмем еще пару раз ОБРАТНО

SI0028

SI0029

И жмем еще раз обратно

SI0030

И оооооопляяяяя! Попали в Активность Е! И попали мы в нее сейчас потому, что на Активности D и других не нажимали кнопку HOME. Вот такое поведение тоже надо учитывать при разработке. Так как Активность с singleInstance может зависнуть в памяти, как мы это только что видели.  Теперь нажмем кнопку Info и посмотрим что там у нас происходит. По идее задача 16 должна была перестать существовать, так как мы закрыли последнюю Активность А в ее стеке.

SI0031

Так и есть. Осталась только одна задача 14 и в ней одна Активность Е. Задача 16 была уничтожена с уничтожением последней Активности в ней, то есть Активности А.

Нажмем кнопку обратно и выйдем из Активности Е и вообще из приложения AP0004.

И будем медитировать на это интересное поведение Активности Е Улыбка 

И заодно может и счетчик пофиксю