Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
12
Добавлен:
20.04.2024
Размер:
13.88 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-x cha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рассмотрим, как работает данный код. Пусть в staging area находятся два файла. Первый — t.php со следующим содержимым:

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

Второй — t.rb с одной строчкой кода:

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-x cha

 

 

 

 

При попытке зафиксировать изменения Git hook не пропустит синтаксически неверный код:

$ git commit -m “magic commit message”

PHP Parse error: parse error in t.php on line 4

Errors parsing t.php

t.rb:1: unterminated string meets end of ile

Aborting commit due to iles with syntax errors

Также мы сразу увидим, в каких файлах и на каких строках у нас синтаксические ошибки.

Запуск Jenkins-задач

И наконец, классический пример continuous integration, который стоит рассмотреть.

Допустим, у нас есть проект в Jenkins, который умеет выгружать из репозитория последние изменения и запускать сборку проекта, прогон интеграционных тестов и прочее. Если ты используешь https://jenkins-ci.org/ https://jenkinsci.org/ Git plugin для Jenkins, то для запуска сборки достаточно вызвать всего одну команду

curl https://jenkins.your_company.com/git/notifyCommit?url=

https://repository.your_company.com/PROJECT

Для этого стоит использовать другой серверный hook с названием post-receive, который запустится после того, как изменения будут приняты в удаленный репозиторий. Более популярное решение — плагин Build Token Root Plugin, где процесс аналогичен.

Собираем все вместе

Для того чтобы обеспечить модульность хуков, можно каждый держать в отдельном файле в директории $GIT_DIR/hooks и подключать их в нужном pre-commit или pre-receive hook.

#!/bin/bash

“$(dirname “$0”)”/check-syntax

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

“$(dirname “$0”)”/block-debugging-code

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-xcha

 

 

 

 

 

“$(dirname “$0”)”/unit-tests

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-x cha

 

 

 

 

Такой подход облегчит поддержку. Кроме того, тебе будет намного проще отключить какой-то из хуков, закомментировав одну строчку.

ЧТО ДЕЛАТЬ, ЕСЛИ НЕТ ДОСТУПА К УДАЛЕННОМУ РЕПОЗИТОРИЮ?

В идеале хуки должны быть серверными и применяться ко всем участникам проекта, но это не всегда бывает возможным. Например, GitHub не позволяет создавать серверные хуки или у тебя не получается договориться с отделом системных администраторов насчет предоставления ssh до системы управления репозиториями. В таком случае придется использовать клиентские хуки и обеспечить их актуальность на машине каждого разработчика. Чтобы не бегать с флешкой по всем машинам, можно использовать Puppet, либо закоммитить hooks в репозиторий и устанавливать их, используя Grunt.

ЧТО ОСТАЛОСЬ ЗА КАДРОМ

Ты можешь использовать Git hooks для автоматизации действий, которые необходимы проекту. Вот еще несколько примеров:

Если ты придерживаешься жестких стандартов форматирования исходного кода в проекте, то можно по аналогии создать хук, который будет запускать php codesniffer, gofmt, pep8 или любую другую утилиту для измененных файлов. Благодаря этому при code review тебе не придется отправлять код на доработку из-за открывающей фигурной скобки не на той строке.

Хочешь сделать снапшоты в веб-камере во время коммита? Проект lolcommits открытым исходным кодом доступен на GitHub. Там же есть небольшая галерея.

Настоящий граммар-наци может сделать хук, который контролирует правописание разработчиков, используя GNU Aspell — бесплатную программу для проверки орфографии.

Автоматизируй рутинные действия и освободившееся время трать на более интересные вещи!

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

 

 

 

 

 

КОДИНГ

 

 

 

df-xchan

 

 

 

w Click

to

 

 

 

 

 

m

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

 

 

 

 

 

e

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

ЛОГГЕРЗВОНКОВ НАANDROID

ИЗУЧАЕМ СИСТЕМУ ОБМЕНА СООБЩЕНИЯМИ НА ЖИЗНЕННЫХ ПРИМЕРАХ

Евгений Зобнин zobnin@gmail.com

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

 

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

Такие приложения, как Tasker и Locale, уже давно ста-

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

 

 

 

 

 

 

p

 

 

 

 

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

ли одним из главных аргументов в споре поклонников Android и iOS. Действительно, обычные, не требующие ни прав root, ни прав администратора приложения,

а позволяют творить со смартфоном такое, что любой ветеран Linux-скриптинга обзавидуется. Как же они работают и почему подобных приложений нет в iOS

и других мобильных системах? Все дело в Binder — IPC/RPC-механизме, пронизывающем весь Android.

ВМЕСТО ВВЕДЕНИЯ

Создатели Android, имея возможность продумать архитектуру ОС с нуля, учитывая современные реалии, закономерно решили изолировать установленные приложения друг от друга. Так появилась идея использовать песочницы, поэтому Android-приложение: а) имеет доступ только к своему собственному каталогу и (если есть такие полномочия) к SD-карте — не содержащей важных данных свалке барахла, б) может использовать только заранее оговоренные возможности ОС (а в Android 6.0 пользователь может отозвать такие полномочия прямо во время работы программы) и в) не имеет права запускать, создавать каналы связи или вызывать методы других приложений.

Реализовано это все с помощью стандартных прав доступа к файлам (в Android каждое приложение работает с правами созданного специально для него пользователя Linux), многочисленных проверок на полномочия доступа к ресурсам ОС на всех уровнях вплоть до ядра и запуска каждого приложения в своей собственной виртуальной машине (сейчас ее уже сменил ART, но сути это не меняет).

Все эти механизмы отлично работают и выполняют свои функции, но есть одна проблема: если приложения полностью отрезаны друг от друга, вплоть до исполнения от имени разных юзеров, то как им общаться и как они должны взаимодействовать с более привилегированными системными сервисами, которые суть те же приложения? Ответ на этот вопрос — система сообщений и вызова процедур Binder, одна из многочисленных находок создателей легендарной BeOS, перекочевавшая в Android.

Binder похож на механизм COM из Windows, но пронизывает систему от и до. Фактически вся высокоуровневая часть Android базируется на Binder, позволяя компонентам системы и приложениям обмениваться данными и передавать друг другу управление, четко контролируя полномочия компонентов на взаимодействие. Binder используется для взаимодействия приложений с графической

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

m

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

.c

 

подсистемой, с его же помощью происходит запуск и остановка приложений,

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

«общение» приложений с системными сервисами. Binder используется даже тогда, когда ты запускаешь новую активность или сервис внутри своего приложения, причем по умолчанию сервис работает в том же процессе, что и основная часть приложения, но его очень легко вынести в отдельный процесс, просто добавив одну строку в манифест. Все будет работать так, как и раньше, и благодарить за это надо Binder.

Сказанное может показаться тебе несколько странным, и, возможно, ты впервые слышишь о каком-то магическом Binder, но это благодаря тому, что Android абстрагирует программиста от прямого общения с этим драйвером (да, он реализован в ядре и управляется с помощью файла /dev/binder). Но ты точно имел дело с интентами, абстрактной сущностью, построенной поверх Binder.

МАГИЧЕСКИЕ ИНТЕНТЫ

В Android объект класса Intent является абстракцией сообщения Binder и по большому счету представляет собой способ передачи управления компонентам своего или чужого приложения, вне зависимости от того, запущено приложение, к которому относится данный компонент, или нет. Банальнейший пример — запуск активности:

Процессобщениякомпонентовприложения через Binder

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

m

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

.c

 

Это пример так называемого явного интента. Есть класс SecondActivity, в ко-

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

тором есть метод OnCreate(), а мы просто говорим системе: «Хочу запустить активность, реализованную в данном классе». Сообщение уходит, система его получает, находит метод OnCreate() в классе SecondActivity и запускает его. Скучно, просто, а местами даже тупо. Но все становится намного интереснее, если использовать неявный интент. Для этого немного изменим наш пример:

И модифицируем описание активности в манифесте:

Результат будет тот же, а возни намного больше. Однако есть одно очень большое но: в данном случае мы использовали не имя компонента, который хотим запустить (SeconActivity), а действие, которое хотим выполнить (com.my.app. MY_ACTION), а формулировка «Я хочу запустить...» превратилась в «Я хочу выполнить такое-то действие, и мне плевать, кто это сделает». В результате нашу активность теперь можно запустить из любого другого приложения точно таким же способом. Все, что нужно, — это указать действие, все остальное система сделает сама.

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

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

m

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

.c

 

Этот простой код позволяет позвонить любому абоненту (при наличии полно-

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

мочия android.permission.CALL_PHONE), а все благодаря тому, что приложение Phone умеет обрабатывать действие Intent.ACTION_CALL (точно таким же способом, как в нашем примере, с помощью intent-filter). Более того, если на смартфоне установлена сторонняя «звонилка», которая умеет реагировать на то же действие, система спросит, какое именно приложение использовать для звонка (а юзер может выбрать вариант, который будет использован в будущем).

Существует множество стандартных системных действий, которые могут обрабатывать приложения, например Intent.ACTION_VIEW для открытия веб-страниц, изображений и других документов, ACTION_SEND для отправки данных (стандартный диалог «Поделиться»), ACTION_SEARCH и так далее. Плюс разработчики приложений могут определять свои собственные действия на манер того, как мы это сделали во втором примере. Но одно действие обязаны обрабатывать все приложения, которые должны иметь иконку на рабочем столе, — это android.intent.action.MAIN. Среда разработки сама создает для него intent-filter и указывает MainActivity в качестве получателя. Так что ты можешь даже не подозревать о том, что твое приложение умеет его обрабатывать, но именно оно позволяет рабочему столу узнать, что на смартфон установлено твое приложение.

Однако все это не так уж и интересно, и в этой статье я бы хотел сконцентрироваться на другом аспекте интентов и Binder, а именно на широковещательных сообщениях.

ШИРОКОВЕЩАТЕЛЬНЫЕ СООБЩЕНИЯ

Одна из замечательных особенностей интентов заключается в том, что это именно сообщения, а значит, их можно использовать не только для запуска компонентов приложений, но и для оповещения о каких-либо событиях и передачи данных. И эта их особенность используется в Android на полную катушку. Система рассылает широковещательные сообщения при возникновении любого сколько-нибудь значимого события: включение и выключение системы, включение экрана, подключение к сети, подключение к заряднику, низкий заряд батареи, входящий и исходящий звонки и многое другое. Даже смена даты приводит к посылке широковещательного сообщения.

Если писать код с учетом всех этих сообщений, можно получить очень умное приложение, способное подстраиваться под работу смартфона и пользователя, а что самое важное — приложение будет обрабатывать эти сообщения вне зависимости от того, запущено оно или нет (точнее, система запустит приложение, когда придет сообщение).

Вкачестве примера приведу ситуацию «из жизни». У меня есть приложение

сполностью зависимым от наличия интернета сервисом. Сервис постоянно

поддерживает подключение к удаленному серверу и ждет команды управления.

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

m

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

.c

 

Обычными методами проблема внезапного отключения от интернета реша-

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

лась бы либо проверкой на наличие интернета перед каждым переподключением к серверу и засыпанием, если его нет, либо отдельным потоком, который бы время от времени просыпался и чекал подключение к интернету, в случае чего пиная основной поток. Недостаток обоих методов в том, что они приводят к задержкам переподключения в момент, когда интернет появляется. Ничего критичного, конечно, но неприятно, да и довольно костыльно-велосипедно.

Но, если приложение будет реагировать на сообщения от системы, эта проблема решится сама собой. Для реализации этого необходимо, чтобы приложение реагировало на сообщение CONNECTIVITY_CHANGE, а затем проверяло, что конкретно произошло: отключение от сети или подключение. Чтобы такое реализовать, нам понадобится ресивер. Для начала объявим его в манифесте, указав нужное сообщение в intent-filter:

Далее создадим сам ресивер ilters/ConnChangeReceiver.java:

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

Ну и добавим в класс NetTools статический метод isConnected():

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

m

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-x cha

 

 

 

 

Я даже не стал добавлять комментарии, тут и так все понятно: при возникновении сообщения CONNECTIVITY_CHANGE запускается ресивер, который проверяет, что произошло, коннект или дисконнект, и в зависимости от этого запускает или останавливает весь сервис целиком. В реальном коде есть еще куча других проверок, а также чекинг подключения с помощью пинга хоста 8.8.8.8 (подключение может быть установлено, но сам интернет недоступен), но это не так важно, а важно то, что простейший код позволяет нам легко избавиться от довольно серьезной проблемы, причем система по максимуму берет работу на себя, и, например, если сервис уже будет запущен к моменту его запуска, ничего не произойдет, второго сервиса не появится. Красота!

Таким же образом я могу запустить свой сервис при загрузке:

Строки из манифеста приводить не буду, скажу лишь, что в intent-filter надо указать действие android.intent.action.BOOT_COMPLETED.

Соседние файлы в папке журнал хакер