dastapov: (new)
[personal profile] dastapov
Я тут потратил несколько вечеров, чтобы написать програмку под андроид. Очень простую (3 активности, пять кнопочек, два calendar view, одна база sqlite). Остаток поста - о том, какие грабли мне попались по пути, и кто, интересно, их там разложил?

Кто пишет под андроид - может почитать и поржать. Кто не пишет, но собирается - может почитать и подумать, так ли оно ему надо? Кто пишет под iOS - может почитать и позлорадствовать, что с Apple все по-другому.

Full disclosure: последний раз я что-то делал на Java четыре года тому назад, и каждый раз, когда у меня возникали какие-то проблемы, я шел прямиком в google и искал по характерным ключевым словам. Я намерено не собирался читать толстых фолиантов типа "The Absolute Definite Android Programming Guide and Reference", т.к. книг много, а хороших книг - мало, да и те быстро устаревают. Так что только гугл + stackoverflow + developer.android.com - такой себе "тяп-ляп и в продакшн".

Первый звоночек был сразу после установки Android Studio. Оказывается, сразу после установки надо сделать определенные действия - открыть SDK manager и скачать все, что оно посчитает нужным. Сама студия об этом молчит - нет, чтобы показать что-то такое при первом запуске. Информация об этом показывается на странице, с которой ты скачиваешь студию, но появляется она там через сколько-то секунд после начала скачивания. Я к этому времени эту страницу уже благополучно закрыл :)

В результате ты рисуешь интерфейс своего первого приложения в графическом дизайнере гуя, и все прекрасно и замечательно, пока ты не добавляешь туда тривиальное поле для ввода текста. И тут твой красивый гуй пропадает, а вместо него появляется загадочная надпись "java.lang.system.arraycopy(ci cii)v". Можно легко проверить, что интернет полон страдальцев, бьющихся головой об эту надпись, а ларчик открывается просто - пока вы не запустите SDK manager, и не накачаете себе всякого разного добра, которое вам предложат по умолчанию, у вашей студии будет только один вариант SDK, который она и будет использовать. Это SDK для Android Wear, то бишь для часов. И куча элементов интерфейса для них просто "не бывает", и вот это самый exception - это способ сообщить пользователю об этом. Я было думал, что это в новой студии такие косяки, а в старом добром эклипсе все ок, но разведчики доносят, что в эклипсе - точно такая же фигня. Ладно, запустил SDK Manager, скачал все что надо, поехали дальше. (ссылка на StackOverflow)

Пару простеньких примеров с developer.android.com собрались, но при попытке запустить их в эмуляторе я обнаружил, что эмулятор запускается через раз. Опытным путем выяснилось, что если попросить "use snapshot", то эмулятор работает, а без этой опции - нет. При помощи strace и такой-то матери было выяснено, что опция "use snapshot" несовместимо с использованием опции "use opengl rendering", и включая-выключая "snapshot" я фактически включал-выключал opengl. А с ним проблемы, если у тебя JDK 7 или выше, linux, используется emulator-arm и луна - в первой четверти. У меня был именно такой JDK, linux, и луной судя по всему тоже повезло, т.к. эмулятор с opengl у меня так и не завелся. Ладно, буду запускать с отключенным, поехали дальше (ссылка на отдаленно имеющих отношение к делу баг, который помог понять, что это в принципе может быть).

Для разминки я решил написать приложение, которое трекает даты. Знаете такие таблички типа "Уже X дней работаем без происшествий"?. Ну вот, чтобы можно было туда вводить даты, оно показывало, сколько дней прошло с последней введенной даты, и можно было посмотреть историю - какие даты вводились раньше и сколько дней между ними прошло. Как раз для разминки - не очень просто, но и не очень сложно.

И вот я делаю в своем приложении MainActivity, у которого в layout есть кнопка, давишь на нее - открывается CalendarActivity, в котором CalendarView, чтобы можно было выбрать дату. И тут у меня начинаются открытия - одно за другим, только успевай записывать.

Во-первых, у CalendarView рекомендуется повесить обработчик на событие onSelectedDateChange, но вот незадача - текущий день уже selected, и сделать так, чтобы никакой день не был selected - нельзя. Но чтобы разработчик не скучал, сделано вот что - если взять и поскроллить календарик (не меняя выбранную дату), то ВНЕЗАПНО выстрелит событие selectedDateChange, возможно даже несколько раз. Интернеты предлагают в обработчике события "изменилась дата" проверять, РЕАЛЬНО ли изменилась дата, и таким образом понимать, изменил пользователь дату или просто поскроллил календарь. Я спасовал против этой логики, выкинул обработчик onSelectedDateChange, и добавил позорную кнопку "Ok", на которую пользователь должен нажать, чтобы подтвердить выбор даты (ссылка на StackOverflow). Тут активность с календарем стала открываться по 10 секунд, но добрая студия подсказала мне, что не надо делать календарю layoutHeight=wrap_content, если другие атрибуты говорят "отдай календарю все, что осталось от других элементов интерфейса".

Далее выяснилось, что внешний вид календаря более-менее прибит гвоздями - текущая неделя всегда выделяется другим цветом фона, а у текущей даты слева-справа от числа будут две "палочки", но это и все. Как сделать у выбранной даты другой цвет фона я так и не нашел, и таких страдальцев, опять же, полон интернет, и всем им советуют - "просто возьмите другой third-party календарь". Теперь я по крайней мере понял, почему во всех приложениях с календарями эти календари разные.

Ладно, я решил, что буду жить со стандартным CalendarView - по крайней мере, пока. Скомпилировал свой пример, поставил на свой телефон, открыл и увидел календарик с мааааахонькими циферками - намного меньшими, чем остальной текст. Как оказалось, у меня на телефоне Android 4.1, а в нем CalendarView поломали - отрисовка дат происходит без использования задаваемого пользователем (или темой) размера шрифтам. В 4.2 уже починили, в 4.0 еще не поломали, а у меня - вот так. Стало еще более понятно, почему все любят кастомные календари. (ссылка на StackOverflow - там видно, как это выглядит).

Ура, теперь у меня работает выбор даты. Дальше я добавил класс для работы с базой SQLite, создал там табличку для хранения дат - все "по учебникам". Даты выбираются, даты сохраняются - красота.

Пришло время считать интервалы между датами. Тут у меня был хитрый план - есть база, sqlite умеет нормально исполнять достаточно сложные запросы, поэтому почему бы не посчитать почти все, что нужно, силами SQL-запроса:
select _id, the_date, prev_date, julianday(the_date)-julianday(prev_date) as duration 
from (select _id,the_date,
             coalesce((select max(the_date) 
                       from dates 
                       where the_date < d.the_date),
                      the_date) as prev_date 
       from dates d) foo;
1|2014-09-01|2014-09-01|0.0
2|2014-09-10|2014-09-01|9.0
3|2014-09-20|2014-09-10|10.0


Засовываю я этот запрос в db.rawQuery("..."), и получают ошибку во время исполнения - "column not found: the_date". Как же как unknown, вот же она! Неа, говорит мне какая-то библиотека из дебрей андроидного SDK, ты мужик меня не обманешь - раз я сказала "нету", значит нету. Как назло, текст ошибки такой, что в гугле находится куча всего постороннего, и 100500 несчастных, которые реально указали не то имя колонки. Но у меня-то в sqlite3 все работает, дело точно в чем-то другом. Попробовав и так и сяк я плюнул и решил, что просто сделаю view, и буду запрашивать данные уже оттуда.

Добавил в метод создания базы вызов db.executeSql("CREATE VIEW AS ..."), и ... получил ту же самую ошибку! Оказалось, что библиотека для работы с sqlite в Android SDK пытается парсить все(!) запросы, которые ты собираешься выполнять. И когда запрос слишком сложный для нее, она валится с вот такой вот диагностикой. Я как-то могу понять, зачем это делать в rawQuery (чтобы получить имена колонок для Cursor-а), но зачем это делать в executeSql - я понять не могу.

Ладно, фиг с ним, посчитаем разницу вручную. Для работы с датами предлагается java.util.Calendar - что в нем есть для подсчета количества дней между датами? Быстрый просмотр доступных методов ничего не дал, и я пошел в гугл. И нашел вот такой ответ на StackOverflow. Настоятельно рекомендую сходить и почитать, памятуя о том, что на дворе у нас 21 век, эра победившего tzinfo и все такое прочее. Вот вам для затравки один из ответов оттуда:
int difference= 
((int)((startDate.getTime()/(24*60*60*1000))
-(int)(endDate.getTime()/(24*60*60*1000))));


Я, каюсь, был насколько впечатлен увиденным, что в результате тоже использовал позорное:
TimeUnit.MILLISECONDS.toDays(curr.getTimeInMillis()-prev.getTimeInMillis());


Короче говоря, приложение я написал, но первое впечатление об андроиде и его SDK у меня сложилось далеко не самое благоприятное. Рассказывайте теперь, как надо было делать правильно :)

(no subject)

Date: 2014-09-09 12:16 am (UTC)
From: [identity profile] jamhed.livejournal.com
Тут еще надо написать что родной эмулятор андроида меееедленный до просто невозможности. Я пользуюсь genymotion которые собрали android для virtual box и прикрутили запускалку в eclipse.

(no subject)

Date: 2014-09-09 06:55 am (UTC)
From: [identity profile] djdance.livejournal.com
+1 использовать эмуль для работы - ну я не знаю, смерти подобно, как минимум. Особенно в андрюше, где чем больше у девелопера разных железок - тем ближе он к безошибочной работе. Но сильно нелинейно)))

(no subject)

Date: 2014-09-09 09:59 am (UTC)
From: [identity profile] restoran.livejournal.com
на Windows 7 с этим эмулятором не только тормоза, но еще и он часто выдает, что не может аллокировать память. Даже если "образцу телефона" указали только 256мб. Вот если его запустить сразу после загрузки винды - то тогда ок.
Собственно, когда я начал смотреть примеры (Delphi XE5), у меня уже был телефон с андроидом, и оказалось намного проще запускать и отлаживать приложение прямо на телефоне, чем на эмуляторе.
Тем более, что эмулятор не даст никакого представления об удобстве пользования приложением "пальцами".

(no subject)

Date: 2014-09-09 12:20 am (UTC)
From: [identity profile] jamhed.livejournal.com
А вообще там граблей много заботливо разложенных в разных местах. Из того с чем я сталкивался:

1. В ведроиде есть встроенный sip-клиент начиная от версии 2.3. Однако часто он отключен вендорами при сборке и не умеет делать эхоподавление, от чего бесполезен полностью. Есть специальная функция установить эходав только она не работает вообще.

2. Ведроид типа штатно умеет играть mp4-потоки, однако все настройки сети там прибиты гвоздями внутри отчего ведроид пытается запустить поток по udp, и если не получилось то по tcp, что приводит к лагу в 5-10 секунд который ничем не убирается.

3. Более-менее приличные библиотеки требуют native-компиляции, и это отдельный ад.
Edited Date: 2014-09-09 12:21 am (UTC)

(no subject)

Date: 2014-09-09 06:59 am (UTC)
From: [identity profile] djdance.livejournal.com
1. я тоже бился с сипом, но ничего толком не нашел, мож посоветуете? Все дико тормозное, и third-party и родное, процент молчаливого неконнекта - 60 (!), потери дикие - чуть что и отвал звука или целиком, качество видеокартинки уровня gif-2000 и 10 фпс... Короче, ни разу не скайп, даже платные либы на сокетах и webrdp или как там. Неужели тупик?

(no subject)

From: [identity profile] jamhed.livejournal.com - Date: 2014-09-09 07:29 am (UTC) - Expand

(no subject)

Date: 2014-09-09 08:50 am (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
эхоподавление не должно бытьфункцией SIP-клиента, что за БУЭ?!

(no subject)

From: [identity profile] jamhed.livejournal.com - Date: 2014-09-09 08:54 am (UTC) - Expand

(no subject)

From: [identity profile] http://users.livejournal.com/_slw/ - Date: 2014-09-09 09:07 am (UTC) - Expand

(no subject)

From: [identity profile] jamhed.livejournal.com - Date: 2014-09-09 09:12 am (UTC) - Expand

(no subject)

From: [identity profile] http://users.livejournal.com/_slw/ - Date: 2014-09-09 09:38 am (UTC) - Expand

"А какая разница?"

From: [identity profile] ext_1684112 - Date: 2014-09-11 12:24 pm (UTC) - Expand

(no subject)

Date: 2014-09-09 05:36 am (UTC)
From: [identity profile] zelius.livejournal.com
В преддверии презентации новых железяк от Apple смотрится (вернее, читается) особенно весело :)))

(no subject)

Date: 2014-09-26 10:31 am (UTC)
From: [identity profile] triampurum.livejournal.com
В iOS все не сильно-то лучше. Те же яйца, вид в профиль.

(no subject)

Date: 2014-09-09 06:12 am (UTC)
From: [identity profile] vp.livejournal.com
Календари.. Зачем вы так далеко ходите? Там само устройство внутренних механизмов - это уже апофеоз убожества. Например, стиль, в котором "рекомендуется" обрабатывать нажатия кнопок. А это значит "давайте сделаем конструктов класса на 100500 строк, а в нем опишем все-все-все обработчики", и в таком духе.
Но тут, конечно, во многом нужно сказать "спасибо" выбранному базовому языку, то есть жабе.

Заборы, коровники.

(no subject)

Date: 2014-09-09 07:00 am (UTC)
From: [identity profile] djdance.livejournal.com
я давно забил и вкладываю лесенкой прямо в 1 строку )

(no subject)

Date: 2014-09-09 06:54 am (UTC)
From: [identity profile] warunlock.livejournal.com
А ссылка на само приложение чтобы все могли восхититься всласть? ;)

(no subject)

Date: 2014-09-10 08:46 pm (UTC)
From: [identity profile] http://users.livejournal.com/_adept_/
Та ну, такого добра - пол-интернета, не буду увеличивать энтропию.

(no subject)

Date: 2014-09-09 06:54 am (UTC)
From: [identity profile] djdance.livejournal.com
ну шо я тебе скажу как дев с 3-летним опытом на яблоке и андрюше. В принципе ты все верно расписал, но, ей-богу, это все та-а-а-акие мелочи, что прям даже тьху. За один простой проект можно огрести на два порядка больше подобного :)

и не стоит уповать на яблоко - там своего добра хватает, только на языке эльфов и без фёрд-пати библиотек. То есть копируй, юзер, вот эту простыню с солюшном и меняй под себя.

а листенер, который не слушает дефолт - проблема многих систем, я еще с лохматого дельфи-2003 приучил себя проверять две весёлые вещи: листенер дефолта и листенер программного чекинга. Первые ты столкнулся, а второе - это когда чекаешь чекбокс в коде. В 50% случаев элемент срабатывает с криком "о, господин юзер меня нажал!"

(no subject)

Date: 2014-09-09 09:18 am (UTC)
From: [identity profile] alex-butenko.livejournal.com
:) я бы еще упомянул как на адроеде работает "кроссплатформенный" phonegap

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 09:31 am (UTC) - Expand

(no subject)

From: [identity profile] alex-butenko.livejournal.com - Date: 2014-09-09 09:45 am (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 09:51 am (UTC) - Expand

(no subject)

From: [identity profile] alex-butenko.livejournal.com - Date: 2014-09-09 09:53 am (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 10:03 am (UTC) - Expand

(no subject)

Date: 2014-09-09 11:13 am (UTC)
From: [identity profile] 13th_doberman (from livejournal.com)
"только на языке эльфов и без фёрд-пати библиотек. То есть копируй, юзер, вот эту простыню с солюшном и меняй под себя."

Прекратите разводить дезинформацию, в CocoaPods в данный момент 3rd-party библиотек — 5,236 (но в это число входит небольшое количество OS X-эксклюзивов), устанавливаются все одной коммандой в терминале, автоматически интегрируются в проект с созданием всех нужных таргетов. Это не говоря уж про библиотеки, которые туда пока что не добавили и которые тихонько на гитхабе живут.

Про языки тоже уточняйте, их сейчас как минимум два, если не считать опенсорсные поделия и RubyMotion.

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 11:39 am (UTC) - Expand

(no subject)

From: [identity profile] madfire.livejournal.com - Date: 2014-09-09 04:03 pm (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 05:42 pm (UTC) - Expand

(no subject)

From: [identity profile] http://users.livejournal.com/__hedin/ - Date: 2014-09-10 04:57 pm (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-10 05:08 pm (UTC) - Expand

(no subject)

Date: 2014-09-09 08:53 am (UTC)
From: [identity profile] 3a_5648.livejournal.com
Нда. Начинаю понимать почему студенты, написавшие что-либо на java, зачет у Столярова потом получают только посредством декана :-) Жалко что телесные наказания отменили, использование java в учебном процессе - это то немногое за что пороть следует.

(no subject)

Date: 2014-09-09 09:30 am (UTC)
From: [identity profile] metaclass.livejournal.com
java тут особо не причем - на ней можно писать нормально (с болью и многословно, конечно, но технически аккуратно).
Но даже продвинутые разработчики часто делают полную чернягу вида "сообщение об ошибке никогда не скажет, в чем именно была ошибка", в основном - из-за checked exceptions, которые всем лень нормально обрабатывать.

(no subject)

From: [identity profile] 3a_5648.livejournal.com - Date: 2014-09-09 11:47 am (UTC) - Expand

(no subject)

From: [identity profile] dil.livejournal.com - Date: 2014-09-09 12:04 pm (UTC) - Expand

(no subject)

From: [identity profile] balmerdx.livejournal.com - Date: 2014-09-09 12:32 pm (UTC) - Expand

(no subject)

From: [identity profile] dil.livejournal.com - Date: 2014-09-09 12:47 pm (UTC) - Expand

(no subject)

Date: 2014-09-09 09:37 am (UTC)
From: [identity profile] djdance.livejournal.com
ну как вам сказать как педагог педагоду... а вы что предлагаете - си? он от жабы не сильно отличается, в поверхностно-педагогическом плане. Делфи мертв. ObjC для эльфов. JS? та же жаба вид сбоку (в педагогическом плане). PHP? пожалуй, но расслабляет. Так что пусть уж жаба, хотя я её не любитель.

ЗЫ если же вы имеете в виду строгость, работу с памятью и прочие фундаментальные вещи (не алгоритмические), то плз оставим это за скобками :)

(no subject)

From: [identity profile] 3a_5648.livejournal.com - Date: 2014-09-09 11:54 am (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 12:03 pm (UTC) - Expand

(no subject)

From: [identity profile] 3a_5648.livejournal.com - Date: 2014-09-09 01:11 pm (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 02:34 pm (UTC) - Expand

(no subject)

From: [identity profile] 3a_5648.livejournal.com - Date: 2014-09-09 04:02 pm (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 05:38 pm (UTC) - Expand

(no subject)

From: [identity profile] 3a_5648.livejournal.com - Date: 2014-09-09 08:37 pm (UTC) - Expand

(no subject)

From: [identity profile] si14.livejournal.com - Date: 2014-09-10 03:11 pm (UTC) - Expand

(no subject)

From: [identity profile] dil.livejournal.com - Date: 2014-09-09 12:08 pm (UTC) - Expand

(no subject)

From: [identity profile] balmerdx.livejournal.com - Date: 2014-09-09 12:34 pm (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 12:36 pm (UTC) - Expand

(no subject)

From: [identity profile] dil.livejournal.com - Date: 2014-09-09 12:50 pm (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 02:24 pm (UTC) - Expand

(no subject)

From: [identity profile] dil.livejournal.com - Date: 2014-09-09 02:44 pm (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 02:55 pm (UTC) - Expand

(no subject)

From: [identity profile] dil.livejournal.com - Date: 2014-09-09 03:20 pm (UTC) - Expand

(no subject)

From: [identity profile] djdance.livejournal.com - Date: 2014-09-09 05:40 pm (UTC) - Expand

(no subject)

From: [identity profile] vragizont.livejournal.com - Date: 2014-09-09 01:48 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2014-09-09 01:59 pm (UTC) - Expand

(no subject)

Date: 2014-09-09 10:50 am (UTC)
From: [identity profile] balmerdx.livejournal.com
На Яве можно писать отличный код. Лично я не вижу сильного отличия между С# и Java в этом плане. На С++ хороший код писать сильно сложнее.

(no subject)

From: [identity profile] 3a_5648.livejournal.com - Date: 2014-09-09 11:55 am (UTC) - Expand

(no subject)

From: [identity profile] balmerdx.livejournal.com - Date: 2014-09-09 12:28 pm (UTC) - Expand

(no subject)

From: [identity profile] 3a_5648.livejournal.com - Date: 2014-09-09 01:16 pm (UTC) - Expand

(no subject)

From: [identity profile] ext_1684112 - Date: 2014-09-11 12:28 pm (UTC) - Expand

(no subject)

Date: 2014-09-09 10:48 am (UTC)
From: [identity profile] balmerdx.livejournal.com
SDK для WP8/Android/iOS написаны довольно хорошо. Что ты и подтвердил своим постом.

(no subject)

Date: 2014-09-09 12:26 pm (UTC)
From: [identity profile] dizel-by.livejournal.com
Рыдаю вместе с автором. А от себя замечу, что сложные вещи Android SDK позволяет делать просто. А простые (и даже элементарные) порой невозможны вообще. Такое ощущение, что сложную часть отдали толковым разработчикам, а на всё остальное посадили даже не индусов, а обезьян из ближайшего зоопарка.

(no subject)

Date: 2014-09-11 06:18 am (UTC)
From: [identity profile] thedeemon.livejournal.com
>сложные вещи Android SDK позволяет делать просто

A можно примеров?

(no subject)

Date: 2014-09-09 05:56 pm (UTC)
From: [identity profile] fukanchik.livejournal.com
Я в своё время получил удовольствие вот от этого:

https://code.google.com/p/android/issues/detail?id=21696

https://issues.apache.org/jira/browse/HARMONY-6542

Там в коде прототип метода
RandomAccessFile#seek(long)
но внутри чуть ли не на первой строчке этот лонг урезается до инта.
From: [identity profile] livejournal.livejournal.com
User [livejournal.com profile] metaclass referenced to your post from "С быстрым компилятором workflow намного более гладкий" (http://metaclass.livejournal.com/890771.html) saying: [...] и методиками деплоймента и пакетными менеджерами, жабы с мавенами, гит, андроиды с корявыми SDK [...]

(no subject)

Date: 2014-09-11 09:00 am (UTC)
From: [identity profile] gleb-kudr.livejournal.com
А на винде этот тупорылый SDK еще и умеет сам отваливаться через каждый запуск, так что когда я писал свой хеллоу-ворд, то деинсталл-инсталл сдк был штатной процедурой...
В общем у меня сложилось впечатление, что разработка под андроид это такие помои, что ни за какие деньги (сам под айось пишу, там только интерфейс xcode кривой в усмерть, с остальным жить можно).

(no subject)

Date: 2015-12-21 03:19 pm (UTC)
From: [identity profile] flakelviv.livejournal.com
А в тебе є бачення, чи щось помінялося з того часу, як ти написав цей пост?

Profile

dastapov: (Default)
Dmitry Astapov

April 2017

M T W T F S S
     12
3 45 6789
10111213141516
17181920212223
24252627282930

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags