События

О чем молчат книги по Android. 5 проблем, о которых не пишут в документации

О чем молчат книги по Android. 5 проблем, о которых не пишут в документации

Ты никогда не задумывался, чем работа программиста отличается, например, от работы инженера-конструктора или прочниста (расслабься, сопромат вспоминать не будем)? Первое, что приходит в голову, — право на ошибки: действительно, процеcc тестирования (отладки) занимает значительное время в любом проекте. Если продолжить размышлять, можно прибавить сюда и динамичность профессии.

В основе инженерных специальностей лежат методики, разработанные десятилетия назад, — так, методу конечных элементов скоро исполнится 70 лет, а он до сих пор не потерял актуальности. В программировании же все меняется со скоростью, близкой к скорости света. И нам приходится постоянно что-то изучать, пробовать чужиe решения, изобретать собственные велосипеды, менять алгоритмы, внедрять стеки новых технологий — словом, участвовать в гонке без финиша. И если инженерам в их работе помогают умные книги, проверенные временем, то в нашем случае найти информацию, порой даже в официальных источниках, бывает очень проблематично. Не веришь? Что ж, тогда добро пожаловать в [А]ндрои[Д]…

Виджет и документация

Сегодня мы рассмотрим Android и его виджеты — только практику, никакой теории. За последней отсылаю тебя к недавней статье, где мы подробно рассматривали процесс создания «хакерского» виджета.

Итак, виджет представляет собой реализацию широковещательного приемника, каркас которого представлен ниже:

public class SkeletonAppWidget extends AppWidgetProvider {    @Override    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {      for (int appWidgetId : appWidgetIds) {        ...        appWidgetManager.updateAppWidget(appWidgetId, views);        Log.d(DEBUG_TAG, "onUpdate : id = " + String.valueOf(appWidgetId));      }    }      @Override    public void onDeleted(Context context, int[] appWidgetIds) {      Log.d(DEBUG_TAG, "onDeleted");      super.onDeleted(context, appWidgetIds);    }      @Override    public void onDisabled(Context context) {      Log.d(DEBUG_TAG, "onDisabled");      super.onDisabled(context);    }      @Override    public void onEnabled(Context context) {      Log.d(DEBUG_TAG, "onEnabled");      super.onEnabled(context);    }  }

Когда пользователь помещает первый экземпляр виджета на домашний экран, срабатывает метод onEnabled(), после удаления которого вызывается парный onDisabled(). Метод onDeleted() вызывается всякий раз, когда пользователь перетаскивает представление экземпляра виджета в корзину.

Метод onUpdate() в цикле обновляет все экземпляры виджета по идентификаторам, хранящимся в массиве, дергая updateAppWidget().

Все сказанное можно найти в официальнoй документации Google, а также в любой книге по программированию под Android. Типичный виджет представлен на рис. 1.

Рис. 1. Обычный виджет

Рис. 1. Обычный виджет

Виджет vs программист

В качестве разминки предлагаю зaбыть половину из того, что мы написали, так как оно не работает! Я не зря поставил отладочную печать всех методов. Запустив код в эмуляторе или на реальном девайсе, можно легко убедиться, что ни onEnabled, ни onDisabled никогда не вызываются в Android 4.4 и ниже! (Чтобы не быть голословным, здесь и далее я тестирую код на устройствах с Android 4.4, 5.1, 6.0.)

Почему так? Видимо, сие есть тайна, доступная только джедаям Google. Вопрос в другом: почему об этом прямо не написать в документации? Особенно доставляют в общем-то правильные по сути механизмы запуска фонового сервиса (или сигнализации) для обновления информации виджетов в onEnabled с остановкой в onDisabled в примерах книг, предназначенных для Android 4. Получается, авторы не тестируют код, который сами же пишут?

Кто-то скажет, что в 5-й версии мобильной ОС это исправлено. Да, исправлено, но сбрасывать со счетов Android 4 пока рано. Кроме того, такие вещи не должны выявляться программистом опытным путем.

Виджет vs здравый смысл

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

<activity android:name=".WidgetSetup" android:label="@string/setup">    <intent-filter>      <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />    </intent-filter>  </activity>

Чтобы назначить для виджета эту активность, нужно добавить ее в соответствующий тег appwidget-provider с помощью атрибута configure, указав полное имя пакета:

<?xml version="1.0" encoding="utf-8"?>  <appwidget-provider    xmlns:android="http://schemas.android.com/apk/res/android"    ...    android:configure="com.hacker.widgetSample.WidgetSetup"  />

Активность настройки ничем не отличается от обычной, но должна указать RESULT_OK в качестве результата и вернуть намерение с дополнительным параметром EXTRA_APPWIDGET_ID, являющимся идентификатором виджета. В противном случае считается, что пользователь отменил свое решение (например, нажал «Назад»), и виджет не будет добавлен.

Фрагмент активности:

Извини, но продолжение статьи доступно только подписчикам

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

1 год

2700 Р

Экономия 1400 рублей!

1 месяц

400 Р

Уже подписан?

Автор: Сергей Куприянов
26.07.2016 (09:30)
Пройди тест и узнай об этом!
Информер новостей
Расширение для Google Chrome

Все права защищены © 2010-2024

"alterprogs.com" - технологии будущего

Контакты  | Карта сайта

Использование любых материалов, размещенных на сайте, разрешается при условии ссылки на alterprogs.com. Для интернет-изданий - обязательна прямая открытая для поисковых систем гиперссылка. Ссылка должна быть размещена в независимости от полного либо частичного использования материалов. Материалы в рубрике "Новости партнеров" публикуются на правах рекламы.