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

Комментарии 51

Хорошая статья, также рекомендую почитать интересующимся книгу Embedded Android.
P.S — В Android используется Toolbox а не Toybox.
Раньше использовался Toolbox, с версии 6.0 Marshmallow перешли на Toybox. Подробнее можно почитать здесь: на LWN и в issue tracker'е.
Embedded Android вышла в 2013 году и базируется на андроиде 4.0, на сколько я помню. Хоть много чего не поменялось, но мне всё же кажется, что книга морально устарела. К примеру Security часть.

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

Псевдоним :)

Программирую под NDK с самого зарождения этой поделки. Я не знаю кто вам сказал что bionic значительно быстрее, меньше и менее требовательна к памяти чем что либо другое — наврал. Сильно. По моим тестам bionic примерно в 5 раз медленнее. А о совместимости хотя бы с ANSI C и говорить не стоит. Мои впечатления хорошо описывает бывший коллега в начале этого доклада https://academy.realm.io/posts/swift-on-android/.

По крайней мере, так утверждают сами Google (видео, слайды). Есть ещё другая известная «лёгкая» libc — musl, у неё гораздо лучше со стандартами, и, возможно, musl и bionic в большой степени объединятся (видео, слайды).
Спасибо за статью. Пишите еще по этой теме. Статей по фреймворку мало, а книг так и вообще по пальцам одной руки можно пересчитать, при этом все они вышли достаточно давно.
> Как легко заметить, использование Android принципиально отличается от использования «обычного Linux» —  вам не нужно открывать и закрывать приложения, вы просто переключаетесь между ними, как будто все приложения запущены всегда. Действительно, одна из уникальных особенностей Android — в том, что приложения не контролируют напрямую процесс, в котором они запущены. Давайте поговорим об этом подробнее

> У приложений Android нет функции main(), нет одной точки входа. Вообще, Android максимально абстрагирует понятие приложение запущено как от пользователя, так и от разработчика. Конечно, процесс приложения нужно запускать и останавливать, но Android делает это автоматически (подробнее я расскажу об этом в следующих статьях). Разработчику предлагается реализовать несколько отдельных компонент, каждая из который обладает своим собственным жизненным циклом.

В результате никогда не знаешь, закрылось приложение, пока ты лазил в словарик, или нет. Невероятно бесит и плохо влияет на продуктивность работы.

НЛО прилетело и опубликовало эту надпись здесь
Быстрее не железо умнее, а софт. И таки да, это вполне нормально. IOS вообще весь закрытый со всех сторон.
НЛО прилетело и опубликовало эту надпись здесь
И в чем проблема с кнопкой?
НЛО прилетело и опубликовало эту надпись здесь
В чем костыльность-то? Для меня, как пользователя аналогичной АКПП, это совершенно неочевидно.
НЛО прилетело и опубликовало эту надпись здесь
1. Степеней свободы там действительно скорее всего две.
Во всяком случае это верно для Mitsubishi. O/D off не просто ограничивает переключение вверх как селектор АКПП, но и меняет алгоритм переключения.

2. Нет, это не означает именно включение, это означает отклонение от некоего дефолтного поведения. Сбойнул датчик и отключилась АБС — загорелась лампа, отключили систему стабилизации — загорелась лампа. То, что люди говорят говорит лишь об их безграмотности, не более того.

3. А она точно нужна — эта индикация?

4. А включение этих режимов и имеет смысл только на спуске для торможения двигателем. Во всяком случае я не могу придумать для чего еще их имеет смысл использовать.

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

По вашей логике владельцы полноценных внедорожников и вовсе не должны с места трогаться из-за дезориентации — там куда больше рычагов и/или кнопок. Про самолеты с целыми панелями выключателей и индикаторов вовсе молчу.
НЛО прилетело и опубликовало эту надпись здесь
Сколько видел автоматов, везде логика одна и та же. Езда с выключенным овердрайвом считается ненормальной — загорается транспарант.
На вполне полноценных внедорожниках в том числе.
Кстати, абсолютно аналогично обстоит дело с раздаткой, когда выключены обе оси, загорается лампа, когда включена одна из осей лампа тухнет.

Мне подобный подход объясняли авиаторы. Любой загоревшийся транспарант это сигнал отхода от нормальной ситуации.
НЛО прилетело и опубликовало эту надпись здесь
При этом ios с гигом памяти не убивает последние приложения моментально. Это действительно бесит когда вышел в вк ответить, а ютуб закрылся на середине просмотра видео. (у меня 2 телефона, android для разработки и youtube из за экрана большего размера). Недавно проверял, кстати, для друга. ios выдержал в памяти gta vicecity, badland2, youtube, vk, whatsapp, safari — при этом я писал видео с экрана. Но тут мне кажется всё таки от вендора зависит больше, как агрессивно будет работать сборщик мусора
Не сборщик мусора, а Lowmemorykiller.

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


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


Если какое-то приложение работает не так (а, например, открывается на стартовой странице), то это неправильно написанное приложение.

Если какое-то приложение работает не так (а, например, открывается на стартовой странице), то это неправильно написанное приложение.

Не всегда. Есть кейсы, когда возобновлять приложение на прежней стадии не нужно, а важнее отобразить актуальные данные. Вообще этот вопрос из области UX и каждый UX-дизайнер и PO дает на него свой собственный ответ в зависимости от своего случая

Отображать актуальные данные нужно всегда, независимо от перезапуска приложения. Но да, в этом плане Android очень гибок и позволяет настраивать такие параметры, как alwaysRetainTaskState (по умолчанию состояние через некоторое время сбрасывается...) и clearTaskOnLaunch, то есть приложение может выбрать оптимальный для своей специфики режим работы.


Но если в результате


Невероятно бесит и плохо влияет на продуктивность работы

то это определённо неправильно сделанное приложение.

Боюсь это означает, что подавляющее большинство приложений в гугл плей написаны неправильно. А это в свою очередь означает, что была выбрана неверная парадигма — то есть, ключевой функционал переложили на плечи прикладных программистов, которые, как и следовало ожидать, забили на это болт. Собственно, это одна из причин, по которым андроид defective by design. Иногда к нему приделывают костыли (возможность «закрепить» приложение, запретить его закрывать), которые немного улучшают ситуацию, но это полумеры.
ключевой функционал переложили на плечи прикладных программистов, которые, как и следовало ожидать, забили на это болт

О каком функционале вы говорите? То, что я назвал — восстановление activity, введённого текста, состояния переключателей, скролла и т.п. — делается автоматически и по умолчанию Android Framewok'ом. Кроме того, разработчику приложения даётся возможность эффективно сохранить и потом восстановить кастомную информацию.


Я бы не назвал это defective by design, совсем нет.


Иногда к нему приделывают костыли (возможность «закрепить» приложение, запретить его закрывать)...

Если вы про screen pinning, то это вообще не для того. Это фича, которая позволяет запретить переключение между приложениями (для снятия запрета требует пароль/код). Используется, например, чтобы ребёнок делал на вашем устройстве только то, что вы ему разрешили, или в embedded Android (разного сорта банкоматы, терминалы...); к app lifecycle это не имеет никакого отношения.


которые немного улучшают ситуацию, но это полумеры.

Посмотрите новые Android Architecture Components, это далеко не полумеры.

Я в данном случае выступаю как пользователь, а не как программист, и соответственно пишу о личном опыте. А опыт таков (и судя по другим комментариям — я далеко не уникален), что большинство пользовательских программ на андроид склонны к спонтанному забыванию текущих данных, то есть соответствуют тому, что вы называете «неправильно написанное приложение.». Ещё раз — подавляющее большинство. Если большинство программистов пишет неправильные программы — это явный проёб в парадигме системы, а как по мне это именно то, что называют «defective by design». Даже странно что вы это отрицаете — у вас что, никогда не было смартфона на android?

Если вы про screen pinning

Нет, совершенно не про это. Просто встречал как-то прошивку, где вместо списка последних запущенных программ — список програм, находящихся в памяти. И соответственно выбрасывание из списка выгружало программу, а закрепление в списке — не позволяло её выгружать (я не знаю, как бы повёл себя Lowmemorykiller если бы я попытался закрепить слишком много программ). И такая система была на порядок удобнее, чем то, что я встречаю в большинстве прошивок.

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

сразу вспоминается palmos (версий до 4.x включительно), система однозадачная, но приложения (по замыслу заработчиков os) открываются моментально и на том же месте, где ты их оставил.
В WebOS что-то переделали разве?
Вот как раз таки нормально влияет на продуктивность работы, в лучшую сторону. Если ОЗУ хватает, то и нечего выгружать приложения. Есть различный уровень у процессов, которые при нехватке памяти выгружаются фреймворком. Их можно глянуть через «adb shell dumpsys meminfo»
Мой опыт показывает ровно обратное. Часть ненужных вещей в фоне крутится до тех пор, пока не тапшешь по виджету очистки памяти, а часть выгружается при любом удобном поводе, хотя свободной памяти еще более, чем достаточно.
У меня сейчас второй смарт и второй компьютер обладают равным количеством ОЗУ, так вот, пользоваться компьютером как многозадачным устройством сильно удобнее.
А вы на смарте пробовали SWAP включать. Я пробовал, ставил 3 Гб, ничего не выгружалось много дней, даже тяжелые приложения. Беда в том, что не все ядра прошивок поддерживают SWAP. У самсунга, например, нет.

Загруженным из свопа файрфоксом пользоваться решительно невозможно. Проще прибить его процесс и запустить заново с загрузкой всех вкладок, чем дожидаться, пока он вылезает из свопа. Причём он не загружается весь сразу, а как-то кусками. Вроде просвопился, всё работает, потом проскроллишь чуток или в соседнюю вкладку тыкнешь, и можно идти заваривать чай, пока он прочухается.


Но своп на смартфоне действительно помогал, правда я не пользовался им уже лет пять — 1 GB оперативки хватает :)

А может быть тут подскажут, есть в кастомных прошивках на основе Nougat такой баг с некоторыми приложениями, в частности приложение Вконтакте, при переключении типа сети WiFi <-> 4G/3G теряет соединение с сетью и пишет «Соединение» пока не выгрузишь и не запустишь заново. При этом другие приложения, не подверженные багу, работают исправно. Что примечательно недавно вышел релиз ParanoidAndroid и там этот баг не проявляется, интересно бы понять в какой подсистеме он может возникать и сравнить что сделали/не сделали в PA в сравнении с LOS, где баг проявляется.

Очень рекомендую к прочтению последнее издание Танненбаума "Modern Operating Systems" где собственно сама Dianne Hackborn написала главу про Андроид (можно довольно легко найти PDF в гугле). Среди разработчиков Андроида эта глава считается одним из самых лучших (хотя и довольно кратких) введений в архитектуру Android.

еще недавно был доклад Эфи Барак
 например, приложение Google Play Services вообще не имеет собственного графического интерфейса для
пользователя, но предоставляет разработчикам других приложений возможность пользоваться сервисами
Google Play.

Это не совсем верно. Многие интерфейсы которые вы видите в Settings на самом деле реализованы в GmsCore. Например, немалая часть Google Play Protect сделана именно там (оставшая часть интерфейса — в Play Store app).

Согласен, но у GPS нет именно собственного интерфейса, нет MainActivity, пользователь не видит это приложение в лончере (хотя в старых версиях Android оно отображалось как Google Settings, но теперь интегрировано в системные настройки).


Подозреваю, что и отображение Maps сделано внутри Play Services. Не подскажете, где почитать про это (и про то, как реализован интерфейс Play Protect) подробнее?

Насчет Maps не уверен, но подозреваю что как минимум часть отображения сделана именно там. UI Play Protect реализован как activity в GmsCore (Play Services), которая каким-то хитрым образом в Android OC цепляется к System Settings (честно говоря, не разбирался как именно) + часть в Play Store.

Почему процессы, созданные через терминал прибиваются через время? Запускал в скрине минимальный сервер на Python aiohttp, работает минут 20. Нагрузки, конечно никакой.
Если это ожидаемое поведение, есть способы «договориться»? Сервисом оформить или по-другому…

Да, нужно оформлять foreground service-ом. Подробнее про это — в следующей статье.

UPD: про это будет в третьей статье.

Расскажите почему в андроид до сих пор не исправили лаги в интерфейсе, а также почему общая скорость работы падает со временем.
Все таки не
нескольких компонент
а
нескольких компонентов


Компоне́нта — составляющая чего-либо; термин, используемый в математике и физике; сфера употребления термина компонента у́же, чем слова компонент, и включает в себя только терминологические контексты

Спасибо, вы совершенно правы. Исправил в статье.

Кое-что не понятно в том, как Binder работает на низком уровне. Приложения его открывают как файл и некоторые данные из него отображаются в память (mmap), так? Когда нужно выполнить метод «с другой стороны», то вызывающее приложение делает ioctl, так? Как отвечающее приложение об этом узнаёт? Оно ждёт в каком-то блокирующем вызове или через select?

Да, ждёт в блокирующем вызове ioctl(binder_fd, BINDER_WRITE_READ, &bwd) — он работает примерно так же, как write() и read() подряд на этом дескрипторе. Вот реализация этого ioctl со стороны ядра.


Да, binder_fd поддерживает и poll, но обычно процессы блокируют свой основной поток (он же looper thread, он же UI thread в приложениях) на binder_write_read и делают остальное блокирующее I/O (например, сетевые запросы) в других потоках.

Отличная и очень полезная для общего развития серия статей! Большое спасибо за информацию, все очень подробно и исчерпывающе подобрано и описано. Побольше бы таких интересных материалов!

Зарегистрируйтесь на Хабре, чтобы оставить комментарий