Двадцать лет назад использовать Android было невозможно. Десять лет назад было еще рано. Сегодня — уже поздно. Конечно, я утрирую, но, когда операционная система молода, многие ее недостатки можно списать на «детские болезни». Их можно понять, простить и не замечать, ожидая скорейших багфиксов от компании-производителя, но… Android уже дорос, пожалуй, до бальзаковского возраста, а мы все так же решаем проблемы, которые давным-давно должны быть исправлены. Сегодня мы рассмотрим те затруднения при разработке под Android, с которыми ты точно когда-нибудь столкнешься. И которые, кстати, дико бесят. 🙂
 

Жизненный цикл Activity может в любой момент перечеркнуть все твои планы

Если ты программируешь под Android, то наверняка видел схему жизненного цикла для самой простой активити. А знал ли ты жизненный цикл окошка с кнопочками, которое создавал компилятор старого и доброго Delphi? Я думаю — нет, не знал, и знать тебе это было не нужно. Интересно, как бы на тебя посмотрели олдскульные дельфисты-паскалисты, если бы ты им сказал: «когда пользователь перевернет свой экран, нам надо пересоздать все формы и восстановить состояние всех компонентов». Скорее всего, они бы пальцем у виска покрутили. И не только потому, что переворачивать старые мониторы и системные блоки было не принято. 🙂

А меж тем Android именно так и устроен: повернул экран — начинай все сначала. Конечно, в настройках ты можешь отключить поворот экрана, но это не всегда удобно, да и рядовые пользователи не знают и десяти процентов возможностей своего смартфона. Поэтому сейчас имеем мы то, что имеем, и единственное, что ты можешь сделать при разработке, — это отключить в манифесте пересоздание Activity, добавив свойства

android:configChanges="keyboardHidden|orientation|screenSize"

Конечно, «знающие люди» так делать не рекомендуют, но такой костыль используют даже серьезные социальные приложения. Если не веришь — посмотри сам манифесты из их APK (вот инструкция).

Дело осложняют и сами производители устройств — каждый из них адаптирует ОС к своим устройствам, меняя в том числе ее поведение. Например, традиционно рекомендуется сохранять данные при событии onStop. Пользователь свернул приложение, и вызвался этот метод. Но есть одна проблема: на некоторых устройствах вызов этого метода не гарантирован. В таком случае нужно сохранять все, что можешь, в методе onPause. Правда, он вызывается не только при выходе из активити, но и при показе диалогового окна, поэтому нужно предвидеть этот момент и предусматривать проверки на показ диалога.

Какой известный лончер для Android сейчас старательно хоронит его производитель?

Загрузка ... Загрузка ...
 

Сбор ошибок, которого не было

Я с тоской вспоминаю старые времена виндовой разработки. Кому нужны системы для сбора ошибок? Да никому! Большинство ошибок лежало «на поверхности», программа или работает, или нет. Если она периодически вылетает — значит, «проклятая винда опять глючит». 🙂 А если она вылетает по вине программиста, то и не страшно, ведь онлайн-сторы программного обеспечения еще не придумали и никто не засыплет твою программу минусами и гневными комментариями. Максимум — под пивко поплачет в жилетку своему дилеру пиратского ПО на Митинском радиорынке.

Сегодня ты лично, оперативно и максимально прозрачно отвечаешь за каждый свой begin и end в Kotlin-коде. Поэтому собирать ошибки нужно сразу при старте приложения.

Систем сбора сейчас расплодилось превеликое множество, но лично я пользуюсь Crashlytics. В ее пользу говорит и то, что ее недавно купила сама Google. Включать сбор ошибок можно для каждой активити отдельно, но проще сразу включить его в классе Application:

@Override
protected void onCreate() {
  super.onCreate(savedInstanceState);
  Fabric.with(this, new Crashlytics());
  try {
    FirebaseApp.initializeApp(this);
    mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
    Crashlytics.log(Log.INFO, "App.onCreate", "Firebase initialized");
  } catch (Exception e) {
    e.printStackTrace();
    Crashlytics.log(Log.ERROR, "App.onCreate",
    "Error initialize Firebase with: " + e.getMessage());
  }
}

Выполнение кода в этом месте может затянуть показ первого экрана приложения, но туда можно через тему поставить свой Splash и убить сразу двух зайцев — подгрузишь инструменты и развлечешь пользователя.

Как видно из приведенного выше кода, один инструмент Google — Crashlytics — следит за работой другого — Firebase. Несмотря на то что оба они могут выполнять одинаковые задачи — собирать события, Crashlytics действует так:

Crashlytics.log(Log.INFO, "App.onCreate", "Firebase initialized");

А Firebase — вот так:

public static void selectContent(String type, String id) {
  if (mFirebaseAnalytics != null) {
    Bundle bundle = new Bundle();
    bundle.putString(FirebaseAnalytics.Param.ITEM_ID, id);
    bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, type);
    mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle);
  }
}
 

Теперь я стреляю у девушек телефон… чтобы отловить на нем баги

Про изменение прошивки производителем ты уже слышал. Но как быть, если неприятность уже случилась и твое приложение, к примеру, стабильно падает у производителя X на устройстве Y с прошивкой Z?

Все бы ничего — подумаешь, одно падение у одного устройства. Но таких устройств было продано несколько миллионов штук, так что гневных отзывов и однозвездных комментариев тебя ждет несколько десятков. Как быть? Использовать фермы для тестирования. Наш материал про семь лучших ферм все еще актуален, советую его прочитать.

Из халявных инструментов я бы предпочел Firebase, который на бесплатном тарифе дает прогнать тесты по десяти реальным устройствам. Кроме того, не забывай погуглить собственные веселые фермы от разработчиков смартфонов. И заводи контакты с людьми, которые работают в магазинах электроники или сервисных центрах (особенно неплохо это получается в маленьких городах). Тогда ты сможешь делать, как я, — брать устройства для тестов у них. Главное, не забудь вернуть гаджет в первоначальное состояние и скрой меню для разработчиков, если оно было заблокировано ранее.

Продолжение доступно только подписчикам

Вариант 1. Оформи подписку на «Хакер», чтобы читать все материалы на сайте

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

Вариант 2. Купи один материал

Заинтересовала информация, но нет возможности оплатить подписку? Тогда этот вариант для тебя! Обрати внимание: этот способ покупки доступен только для материалов, опубликованных более двух месяцев назад.


3 комментария

  1. baragoz

    08.05.2018 at 14:58

    Знал, что настанут времена и Дельфи с его 200Кб программой — хеллоувордом будут вспоминать добрым словом 🙂

  2. vaca

    09.05.2018 at 11:14

    Вот посмотришь WWDC, а там про десятки новых функций API, фреймворки встроенные, мастерклассы для разработчиков по ним. У гугла на IO есть что-то или рассказывать не о чем и незачем, если новая версия к следующей конфе наберёт процентов 10?

  3. Atos4444

    13.05.2018 at 09:49

Оставить мнение

Check Also

Энкодеры msfvenom. Разбираемся с кодированием боевой нагрузки при бинарной эксплуатации

Генерация полезной нагрузки — неотъемлемая часть эксплуатации. При использовании модулей M…