Как стать автором
Обновить

aMinskBuses или несколько попыток переноса расписания автобусов в Android смартфон

Я еще не совсем осознал то, что моя идея с треском проваливается, но, кажется, дела обстоят именно так.
Проект aMinskBuses изначально был задуман, чтобы перенести расписания всех минских автобусов и троллейбусов в самое подобающее им место – в мобильный телефон. Операционной системой был выбран Android. По-мойму идея неплохая: подойдя к остановке, выбрать нужный маршрут и узнать сколько осталось ждать. Ну и всякие плюшки с поиском ближайших остановок и напоминаниями в календаре тоже не лишние.
Конкурс для разработчиков Android приложений, объявленный одним известным в наших краях сотовым оператором, оказался как нельзя кстати. Такое удачное стечение обстоятельств нельзя было упускать, и я решился серьезно взяться за первый собственный проект.

Первые грабли комом


Первая схема, по которой должно было работать это приложение, была незатейлива, как грабли. Файлы с расписаниями должны были качаться на телефон с сервера, далее там уже разбираться и сохраняться в БД телефона. После чего можно было бы установить интервал обновления этой самой базы и прочее-прочее. Это самый первый вариант, который пришел мне в голову. Признаюсь, до этого я никогда не писал под телефоны и со многими подводными камнями знаком не был.
Написав небольшой кусок кода, который, тем не менее, занял у меня достаточно много времени, я понял – разбирать текстовые файлы на телефоне дело жутко не благодарное, особенно учитывая то, что файлы не такие уж и маленькие (суммарно больше Мб сурового дампа базы). Разбор одного не самого большого файла у меня занимал больше 15 секунд. Я отлично понимал, что, даже увеличив производительность в 5-10 раз, мне еще предстояло поместить эти данные в SQLite базу, а такие перемещения заняли бы слишком много времени. Обновление расписания за 2-е минуты (думаю это минимум) теряет свою актуальность – я бы и сам не стал ждать столько.
Идея с разбором расписания на самом телефоне была отметена.
Стоит отметить, что на этот момент у меня была уже куча материалов в голове и на бумаге. Если чуть подробнее, то я уже зарисовал (в карандаше), как я вижу себе все screen’ы в телефоне и исписал целый ворох бумаг мыслями, которые могли ускользнуть в процессе разработки.
Чуть не забыл, еще был МинскТранс, в котором меня заверили, что расписание может меняться по пять раз на дню. Также мне было поставлено условие: расписание должно было быть актуальным на текущий момент. И вообще, это отдельная история как я ездил в МинскТранс, если кому-нибудь интересно – могу рассказать отдельным постом.

Второй ход


Сдаваться я не собирался. Следующая идея, которая меня посетила, заключалась в переносе всей ресурсоемкой части на web-сервер. Идея отличная, как показалось мне. Сервер забирает все те же злосчастные файлы и сохраняет их у себя в базе. Все это делается через определенные промежутки времени – тем самым поддерживается актуальность данных.
Сервер так же должен был обладать набором web-сервисов, позволяющих получать только нужную информацию на телефон без излишков – экономия трафика и все счастливы.
Для площадки для своего сервиса я выбрал небезызвестный AppEngine от Google. Почему? Ответ очевиден – он бесплатный и он на Java. Мне именно это и было нужно. Тратить кровно заработанные деньги не было особого желания.
Я решил использовать Spring Framework как основу для своего сервиса и это решение сопровождало меня постоянно. Проектирование внешнего интерфейса прошло несколько стадий.

Попробуем SOAP

Изначально я планировал обернуть результат в SOAP и в таком виде разбирать его уже на клиенте (т. е. мобильном телефоне). Данный протокол был выбран мною неспроста, я каждый день сталкиваюсь с ним на работе и от этого он мне близок. Почитав, что об этом думают зарубежные коллеги пришел к выводу, что это не лучшая идея – слишком тяжелый SOAP как контейнер для передачи информации, а разбор на мобильном устройстве опять мог вызвать проблемы с производительностью, да и лишний расход трафика не является преимуществом.

Откинем лишнее или голый XML

На втором шаге проектирования, я решил использовать просто XML. Опять же, он мне близок и уже меньше по объему, чем тот же SOAP с XML внутри. Для того чтобы с наименьшими расходами преобразовать объекты Java в XML я решил использовать XStream. В моем понимании это удобно и красиво. Первым барьером было то, что XStream не захотел работать в AppEngine в таком виде, в котором он был скачан. Разобравшись в проблеме, оказалось, что все, что надо — это внести некоторые изменения в код этой библиотеки. Честно признаюсь, я был очень рад, когда объект простейшего класса из двух полей с легкостью преобразовался в XML и засветился в моем окне браузера с красивой подсветкой. Надо отметить, что радость моя была совершенно не долгой. Написав уже порядочно кода и расставив где надо аннотации, я решил испытать этот кусок кода. Тест был проще некуда: одним методом в datastore заносились данные, другим они оттуда доставались и выводились. Тест провалился – оказалось, что сочетание особенностей безопасности в AppEngine и механизма сериализации библиотеки XStream не позволяют сделать XML из объекта, полученного из datastore. Решить данную проблему у меня так и не получилось. Я стал искать другую библиотеку для сериализации объектов в XML. Перебирая их одну за другой, я их браковал по тем или иным причинам. После XStream все они казались ненужно сложными и громоздкими. В процессе поисков я наткнулся на один интересный вариант — Jackson.

JSON — быстрее, легче, а все равно удобно

Так я дошел до третьего варианта внешнего интерфейса. Дело все в том, что Jackson позволяет преобразовывать объекты в другой, пусть и менее распространенный, формат JSON. JSON для меня был форматом новым, до этого я его использовал только вскользь и знания в этой области были отрывочны. Оказалось, что разобрать JSON в Android проще простого, и этот формат идеально подходил для моего приложения, ведь он еще легче XML. Сразу же проверил Jackson в AppEngine и, в том числе, возможность сериализации объектов полученных из datastore. Все работало отлично и я решил остановиться на этом варианте как окончательном.

Неделя сурового кодинга и часть сервиса, которая должна вытаскивать всю необходимую информацию и укладывать ее в datastore, практически написана. Закрались несколько багов, куда без них. Но это скорее издержки, потому как писал ночами, после 8-ми часового рабочего дня и усталость оказывала на меня свое губительное влияние. Debug’ер мне в помощь – все баги отловлены за один вечер и сервис готов к запуску.
Скрестив пальцы, я запустил его у себя локально. Вызываю нужный метод и жду. Мне показалось, что ждал я вечность, но на самом деле все прошло за каких-то 20-30 секунд. Данные у меня, они готовы к использованию – несколько тестов, и действительно все работает и возвращает красивенькие файлы в формате JSON.
На этом эпопея не закончилась, как оказалось. Нет, я предполагал, что придется еще раз заняться debug’ом после переноса на реальный сервер, но ошибок оказалось немного больше, чем я думал. Локально и на далеких Google’вских серверах все работало «чуть-чуть» по-разному. Ну да ничего, думал я, и стал отлавливать новую пачку bug’ов. И вот тут подкрался еще одна неудача, которая на данный момент оказалась неразрешенной.
Дело в том, что данных получалось достаточно много – не такой уж и маленький город. В общем, запускаемый мною метод просто-напросто убивался по таймауту (есть такая вещь в GAE, если кто не знает, составляет 30 секунд), не успев запихать в базу все, что должен был.

Этот пост можно считать бортовым журналом проекта aMinskBuses в кратком художественном описании. Если будет свободное время – я опишу несколько нетривиальных проблем, с которыми я столкнулся в процессе написания своего сервиса, и их решения. Практически все они связаны с особенностями написания приложений под AppEngine, и использованием там таких фреймворков как Spring 3.0, XStream и Jackson.

Напоследок, хотелось бы отметить – я до сих пор ищу вариант, который мог бы спасти мою идею, но надежда как-то меркнет. Думаю, у меня еще есть шанс, и я не собираюсь сдаваться. Правда, стоит признать, что изначальный стимул я потерял, так как явно не успеваю закончить и предоставить приложение на конкурс.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.