Pull to refresh

Best practices от Google по разработке Android приложений

Reading time8 min
Views45K
В данной статье я хотел бы вкратце рассказать про самые последние best practices от Google. Я постарался выделить самые основные моменты, чтобы читатель сразу мог понять, что именно какая-либо фича дает разработчику. Не удивляйтесь, если где-то повторяюсь. Конспектировал + добавлял от себя по ходу просмотров видео в www.youtube.com/channel/UCVHFbqXqoYvEWM1Ddxl0QDg

Также к каждому пункту приводятся все необходимые ссылки для более подробного ознакомления с конкретной best practice.

Best practices. UI


1. Использование hardware accelaration. Позволяет улучшить плавность ui, анимации за счет предарительной отрисовки и хранения этих отрисовок в памяти (вместо динамической постоянной отрисовки и перерисовки)

2. Для кастомных View или анимаций (прозрачность и прочее), рекомендуется использовать hardware accelaration. Пример:

View.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);
animator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        view.setLayerType(View.LAYER_TYPE_NONE, null);
    }
});
animator.start();


3. В кастомной view, если метод переопределить метод hasOverlappingRendering и возвращать false, то view нельзя будет задавать альфу прочее, зато производительность в раза два поднимется.

Ссылка: www.youtube.com/watch?v=wIy8g8yNhNk&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=9
По этой ссылке — developer.android.com/guide/topics/graphics/hardware-accel.html — еще советы по оптимизации UI

4. В onDraw не рекомендуется создавать объекты (типа Paint и т.д.). Данные объекты можно сделать статическими — это экономия памяти + предварительное создание + отсутствие постоянного вызова gc.
Ссылка: www.youtube.com/watch?v=HAK5acHQ53E&index=10&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE

5. Tools: Strict mode. Данная тулза настраивается в настройках разработчика на устройстве. Она позволяет отловить все потенциально узкие места в UI (что-то тормозит, где-то блокируется UI — ThreadPolicy). Также можно отловить memoty leaks (VMPolicy). Настроить режим для приложения можно через соответствующий класс — developer.android.com/reference/android/os/StrictMode.html

6. При создании custom view.
View.invalidate() — вызывает перерисовку элемента. Это зло. Если что-то поменялось, то нужно перерисовывать не весь view, а конкретный Rect (если он видим пользователю).

Не рисовать лишнее. Что не видно, то не рисовать. Банально, но часто этим пренебрегают. Canvas.clipRect() в помощь. Также для быстрого определения, что слой не видим — Canvas.quickReject(...)

Не перегружать слишком в угоду другому CPU и GPU.

Ссылка:https://www.youtube.com/watch?v=zK2i7ivzK7M&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=12

7. Bitmap. Желательно подгружать предварительно сжатые картинки с помощью BitmapFactory.Options
developer.android.com/training/displaying-bitmaps/load-bitmap.html

8. Bitmap. При создании Bitmap из картинки (jpeg, png) по умолчанию используется формат ARGB_8888 (32 бита на пиксель). Если критичен вопрос памяти, можно использовать другие форматы (RGB_565 — 16 бит и другие). Выставление данного параметра происходит через BitmapOptions. Конвертация, конечно же, сказывается на производительности.

Ссылка: www.youtube.com/watch?v=1WqcEHXRWpM&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=14

9. www.youtube.com/watch?v=2TUvmlGoDrw&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=15 — разные форматы картинок
новый гугловский формат (качество то же, размер меньше) — developers.google.com/speed/webp/?csw=1

10. Масштабирование в BitmapOptions для экономии памяти при загрузке картинок с высоким разрешением
www.youtube.com/watch?v=HY9aaXHx8yA&index=16&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE
developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap

11. Overdraw. Заставляет GPU работать вхолостую (рисование скрутытх элементов). Для определения overdraw, нужно в DeveloperOptions включить Show GPU Overdraw flag. Также помогает тулза ViewHierarchy.

Ссылка: www.youtube.com/watch?v=T52v50r-JfE&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=22

12. TraceView также хорошо подходит для определения корректности отрисовки. Все отрисовки должны помещаться в 16 мс (60 кадров в секунду).

Ссылка: www.youtube.com/watch?v=HXQhu6qfTVU&index=21&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE

13. VSYNC. Что это такое.
Refresh rate (60 hz) — это частота обновления экрана, константа. Frame rate — частота обновления фрейма в секунду. Единица измерения GPU.

Обе скорости должны быть синхронизированы для корректного отображения. Для решения данной проблемы используется двойная буферизация. С GPU картинки идут в back buffer, а затем в frame buffer, а оттуда на экран. Между back buffer и frame buffer находится VSYNC, который следит за тем, чтобы данные с back buffer переходили в frame buffer синхронно скорости обновления экрана. Это устраняет возможные коллизии картинки на экране.

Скорость работы GPU (frame rate) должна быть выше скорости обновления экрана (refresh rate) для того, чтобы ui был плавным.
www.youtube.com/watch?v=1iaHxmfZGGc&index=23&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE

14. Tool — Profile GPU Rendering
Подключить можно в DeveloperOptions. Нам интересен граф для приложения. Есть еще для навигации и notification bar. Сам график представляет собой совокупность времен, требуемых на прорисовку frame. График не должен превышать зеленую вертикальную линию — 16ms (скорость обновления экрана).

Состав графика хорошо описан в видео ниже. Все довольно понятно:
www.youtube.com/watch?v=VzYkVL1n4M8&index=24&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE

15. Работа CPU и GPU на русском хорошо расписана в www.youtube.com/watch?v=zVK6TKSx1lU&feature=iv&src_vid=VzYkVL1n4M8&annotation_id=annotation_3064896115
Критично для игр)

16. Почему мы должны придерживаться скорость 60 fps — www.youtube.com/watch?v=CaMTIgxCSqU&index=25&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE

17. Android UI and the GPU
GPU нужен для растеризации полигонов, текстур. CPU отдает GPU необходимые графические элементы и с помощью OpenGL эти элементы конвертируются в полигоны и текстуры и хранятся в GPU (нужно уточнить?). Плюс другие оптимизации GPU: отрисовка не всего экрана, а изменяемых частей, объединение элементов в полигоны и т.д.:
www.youtube.com/watch?v=WH9AFhgwmDw&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=26

18. Show GPU view updates in DevOps — показывает, какие элементы invalidate()

Best practices. Коллекции


1. По default для перебора всех элементов коллекции рекомендуется использовать Итератор.
Но в критических ситуациях встает вопрос выбора самого быстрого способа перебора. Самые лучшие показатели принадлежат ArrayList с перебором по индексу.
Ссылки: developer.android.com/training/articles/perf-tips.html#Loops, www.youtube.com/watch?v=MZOf3pOAM6A&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=6

Best practices. Способы синхронизации. Энергосберегающие


1. JobScheduler + github.com/evant/JobSchedulerCompat (для версий < 21). Средство, формирующее очередь для фоновых операций (особенно работа с сетью), и организующее их выполнение равными кусками для эффективного энергосбережения батареи (радио пребывает в активном и выжидающем режиме малое количество времени). Для задач мы задаем условия, когда, с какой периодичностью, при каком соединении и т.д. они должны запускаться.

2. SyncAdapter. Старое решение. Много кода + собственный ContentProvider.

3. GCM. Как замена JobScheduler — developers.google.com/cloud-messaging/network-manager. Позволяет производить синхронизацию не путем периодического опроса сервиса, а получением от GSM сообщения об изменении чего-то в сервисе, собственно, необходимо обновиться и клиенту. Плюс только сообщения GSM будут доходить до устройства в режиме глубокого сна (M version)

4. Firebase Offline. Оффлайн синхронизация.

5. AlarmManager. Задается два типа времени запуска/повтора: inexact (время коррелируется с временем запуска других приложений для экономии батарейки, рекомендуется), exact (точное время, не рекомендуется)

Best practices. Battery


1. Для отслеживания работы батареи в приложении можно использовать:
— Настройки приложения
— battery-historian (https://github.com/google/battery-historian)

Для экономии батареи с случаях, когда необходимо делать какие-либо периодические запросы, рекомендуется — JobScheduler
Куда уходит батарея — research.microsoft.com/en-us/people/mzh/eurosys-2012.pdf Хороший research:
www.youtube.com/watch?v=9i1_PnPpd3g&index=29&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE

Best practices. Память


1. Object pools ( www.youtube.com/watch?v=bSOREVMEFnM&index=5&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE ). Для самостоятельного контроля над памятью, выделяемой для тяжеловесных объектов (типа Bitmap и прочее). Необходимо для того, чтобы контролировать, когда должен срабатывать GC — скорость и плавность работы приложения.
Возможные решения: LRUCache, Pools (https://developer.android.com/reference/android/support/v4/util/Pools.html), FlatBuffers (https://google.github.io/flatbuffers/ )

2. Думаю, обычного LRUCache вполне должно хватить

Best practices. GC


1. Сравнение Dalvik and ART — source.android.com/devices/tech/dalvik
Как пример, у ART улучшенная работа GC благодаря, в том числе, и параллелизации работы GC:
www.youtube.com/watch?v=pzfzz50W5Uo&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=34

Google play services 7.5


1. Cloud messaging. Отправка сообщений с определенными темами, NetworkManager, повторяющий в принципе JobScheduler
developers.google.com/cloud-messaging

2. App invites. Приглашение от друга
developers.google.com/app-invites

3. Smart lock for passwords. Если юзер под своим аккаунтом на мобиле, и, к примеру, он заходил на приложение с браузера и сохранял пароль, то в приложении аутенфикация проходит автоматически: developers.google.com/identity/smartlock-passwords/android

Про эти нововведения и остальные здесь — developers.google.com/app-invites

Voice interaction


Управление приложением через голосовые команды. По ходу только с M версии.

io2015codelabs.appspot.com/codelabs/voice-interaction#1
developers.google.com/voice-actions

Новое и интересное


1. Fingerprint API (по пальцу) и Confirm credential(криптографически)
www.youtube.com/watch?v=VOn7VrTRlA4&index=11&list=PLOU2XLYxmsIJDPXCTt5TLDu67271PruEk
2. В M version в Настройках можно просмотреть, сколько приложение потребляет трафика и т.д.
3. Data binding в будущем (задание списка и даты прямо в xml)
4. RecyclerView ItemTouchHelper — Swipe-to-dismiss, Drag&Drop
5. При setAlpha hardware будет подключаться автоматически

Просто интересное


1. External storage — no hard code! Никогда не используйте при задании пути к файлу строчек типа — "/sdcard/" (то есть не задавайте путь до файлу вручную). Для этого есть специальные методы типа «Environment.getExternalStorageDirectory().getAbsolutePath()», которые всегда вернут вам корректный путь до файла, что не гаранировано при ручном задании.

Android studio


1. Поддержка SVG формата
2. Новый компилятор Jack
3. PNG Cruncher?
4. Coming: aapt
5. Studio 1.3 + Gradle 2.4 = большой прирост в скорости сборки
6. Data binding экспериментально доступен сейчас
7. Coming soon: Cloud test Lab, Google play testing
8. NDK support
9. Новые аннотации (WorkThread и т.д.)
10. Android Typed Integer — теперь будет видно, что какой-либо флаг означает
11. Capture view: Heap snapshot, Allocation tracking и т.д. — позволяет просматривать утечки памяти и прочее
12. Простое подключение гугловских сервисов (аналитика, облако и т.д.)
13. Theme editor
www.youtube.com/watch?v=f7ihSQ44WO0

Интересные библиотеки


1. Libraries for developers. Много интересных UI решений

Заключение


Надеюсь, статья вам понравится и будет интересна! Это моя первая статья, поэтому в случае получения вами положительных эмоций и знаний, жду инвайта. Если есть что добавить, либо поправить, жду комментов.
Tags:
Hubs:
+28
Comments18

Articles

Change theme settings