Post on 05-Dec-2014
description
Dependency Injection в Android
Кирилл Бояршинов
Android Developer, Live Typing
Almaty Google Technology User Group
Almaty Google Technology User Group
О себе
О себе• Закончил ОмГТУ (АСОИУ)
О себе• Закончил ОмГТУ (АСОИУ)• Делаю крутые приложения в Live Typing: • КоммерсантЪ • Breath Alcohol Monitor (by Lapka) • PrizeWord сканворды • Опросы Департамента транспорта Москвы
О себе• Закончил ОмГТУ (АСОИУ)• Делаю крутые приложения в Live Typing: • КоммерсантЪ • Breath Alcohol Monitor (by Lapka) • PrizeWord сканворды • Опросы Департамента транспорта Москвы
• Участник GDG Omsk
О себе• Закончил ОмГТУ (АСОИУ)• Делаю крутые приложения в Live Typing: • КоммерсантЪ • Breath Alcohol Monitor (by Lapka) • PrizeWord сканворды • Опросы Департамента транспорта Москвы
• Участник GDG Omsk• Огранизатор Android Developers Omsk
О себе• Закончил ОмГТУ (АСОИУ)• Делаю крутые приложения в Live Typing: • КоммерсантЪ • Breath Alcohol Monitor (by Lapka) • PrizeWord сканворды • Опросы Департамента транспорта Москвы
• Участник GDG Omsk• Огранизатор Android Developers Omsk• Увлечения: космос, спорт, open source
Внедрение зависимостей (Dependency Injection)
Внедрение зависимостей (Dependency Injection)
• Набор паттернов и принципов разработки ПО
Внедрение зависимостей (Dependency Injection)
• Набор паттернов и принципов разработки ПО• Позволяют писать слабосвязный код
Внедрение зависимостей (Dependency Injection)
• Набор паттернов и принципов разработки ПО• Позволяют писать слабосвязный код• Является разновидностью более глобального принципа инверсии управления (Inversion of Control) (by M.Fowler)
Внедрение зависимостей (Dependency Injection)
• Набор паттернов и принципов разработки ПО• Позволяют писать слабосвязный код• Является разновидностью более глобального принципа инверсии управления (Inversion of Control) (by M.Fowler)
• Разделяет порождение компонентов, от тех, кто их запрашивает
Component Service
Assembler
Component Service <<interface>>
ServiceImpl
<<request>>
<<create>>
<<inject>>
Принцип DI
public class Component { private final Service service; public Component(Service service) { this.service = service; } public void doStuff() { return service.doStuff(); } }
JSR-‐330
• @Inject • @Named • @Qualifier • @Scoped • @Singleton
Java Frameworks
• Spring • Guice • PicoContainer • Avalon • …
Цели “ObjectGraph”
Цели “ObjectGraph”
• Статический анализ всех зависимостей и инъекций
Цели “ObjectGraph”
• Статический анализ всех зависимостей и инъекций
• Compile-‐time валидация и поиск ошибок
Цели “ObjectGraph”
• Статический анализ всех зависимостей и инъекций
• Compile-‐time валидация и поиск ошибок• Избавиться от рефлексии
Цели “ObjectGraph”
• Статический анализ всех зависимостей и инъекций
• Compile-‐time валидация и поиск ошибок• Избавиться от рефлексии• Незначительные затраты памяти
Разработка “ObjectGraph”
Разработка “ObjectGraph”• 5 недель работы Jesse Wilson• Bob Lee в качестве технического советника
Разработка “ObjectGraph”• 5 недель работы Jesse Wilson• Bob Lee в качестве технического советника• “Огромный” boolean switch в приложениях Square
Разработка “ObjectGraph”• 5 недель работы Jesse Wilson• Bob Lee в качестве технического советника• “Огромный” boolean switch в приложениях Square• Через 2 недели Guice был полностью удален
Разработка “ObjectGraph”• 5 недель работы Jesse Wilson• Bob Lee в качестве технического советника• “Огромный” boolean switch в приложениях Square• Через 2 недели Guice был полностью удален• Переименован в Dagger
Разработка “ObjectGraph”• 5 недель работы Jesse Wilson• Bob Lee в качестве технического советника• “Огромный” boolean switch в приложениях Square• Через 2 недели Guice был полностью удален• Переименован в Dagger• Выложен в открытый доступ -‐ http://github.com/square/dagger
Dagger
Dagger• ObjectGraph -‐ центральный менеджер зависимостей и инжектор
Dagger• ObjectGraph -‐ центральный менеджер зависимостей и инжектор
• @Module + @Provides -‐ механизм предоставления зависимостей
Dagger• ObjectGraph -‐ центральный менеджер зависимостей и инжектор
• @Module + @Provides -‐ механизм предоставления зависимостей
• @Inject -‐ механизм для запроса зависимостей
Dagger• ObjectGraph -‐ центральный менеджер зависимостей и инжектор
• @Module + @Provides -‐ механизм предоставления зависимостей
• @Inject -‐ механизм для запроса зависимостей• И еще немного сахара и магии :)
Предоставление зависимостей
Предоставление зависимостей• Модули -‐ классы, предоставляющие зависимости
Предоставление зависимостей• Модули -‐ классы, предоставляющие зависимости• Для этого у класса-‐модуля используется аннотация @Module
Предоставление зависимостей• Модули -‐ классы, предоставляющие зависимости• Для этого у класса-‐модуля используется аннотация @Module
• Аннотация @Provides у метода указывает, что возвращаемый тип -‐ зависимость
Предоставление зависимостей• Модули -‐ классы, предоставляющие зависимости• Для этого у класса-‐модуля используется аннотация @Module
• Аннотация @Provides у метода указывает, что возвращаемый тип -‐ зависимость
• @Module и @Provides предназначены использоваться вместе
@Module public class ServiceModule { @Provides public Service provideService() { return new ServiceImpl(); } }
Инъекция зависимостей
Инъекция зависимостей• Инъекция в конструктор:
Инъекция зависимостей• Инъекция в конструктор:• @Inject у конструктора
Инъекция зависимостей• Инъекция в конструктор:• @Inject у конструктора• Все аргументы конструктора -‐ зависимости
Инъекция зависимостей• Инъекция в конструктор:• @Inject у конструктора• Все аргументы конструктора -‐ зависимости• Зависимости могут быть сохранены в private и final полях
Инъекция зависимостей• Инъекция в конструктор:• @Inject у конструктора• Все аргументы конструктора -‐ зависимости• Зависимости могут быть сохранены в private и final полях
• Dagger должен создавать объект
Инъекция зависимостей• Инъекция в конструктор:• @Inject у конструктора• Все аргументы конструктора -‐ зависимости• Зависимости могут быть сохранены в private и final полях
• Dagger должен создавать объект• Для такого объекта не требуется @Provides (т.е. его можно использовать как зависимость)
public class Component { private final Service service; @Inject public Component(Service service) { this.service = service; } public void doStuff() { return service.doStuff(); } }
Инъекция зависимостей
Инъекция зависимостей• Инъекция в поле:
Инъекция зависимостей• Инъекция в поле:• @Inject у полей-‐зависимостей
Инъекция зависимостей• Инъекция в поле:• @Inject у полей-‐зависимостей• Поля не могут быть private или final
Инъекция зависимостей• Инъекция в поле:• @Inject у полей-‐зависимостей• Поля не могут быть private или final• Инъекция происходит после создания объекта
Инъекция зависимостей• Инъекция в поле:• @Inject у полей-‐зависимостей• Поля не могут быть private или final• Инъекция происходит после создания объекта• Чаще всего объект ответственен за инъекцию самого себя
public class Component { @Inject Service service; public Component() { Injector.inject(this); } public void doStuff() { return service.doStuff(); } }
ObjectGraph
ObjectGraph• Центральный контроллер модулей (зависимотей)
ObjectGraph• Центральный контроллер модулей (зависимотей)• Инжектор
ObjectGraph• Центральный контроллер модулей (зависимотей)• Инжектор• Может быть расширен путем добавления других модулей.
ObjectGraph• Центральный контроллер модулей (зависимотей)• Инжектор• Может быть расширен путем добавления других модулей.
• Модули могут переопределять зависимости из других модулей (только 1 раз)
ObjectGraph og = ObjectGraph.create( new NetworkModule(), new TwitterModule("naghtarr") ); '// Using constructor injection: TweeterApp app = og.get(TweeterApp.class); '// Using field injection: TweeterApp app = new TweeterApp(); og.inject(app);
Листинг объектов для инъекций
Листинг объектов для инъекций
• Все объекты для инъекции должны быть перечислены в модуле
Листинг объектов для инъекций
• Все объекты для инъекции должны быть перечислены в модуле
• Используется для статического анализа зависимостей
@Module public class ServiceModule { @Provides public Service provideService() { return new ServiceImpl(); } }
@Module( injects = { Component.class } ) public class ServiceModule { @Provides public Service provideService() { return new ServiceImpl(); } }
Как пользоваться в Android
Как пользоваться в Android• Корневой ObjectGraph создается в подклассе Application
Как пользоваться в Android• Корневой ObjectGraph создается в подклассе Application
• Не получится использовать инъекцию в конструктор (объекты создаются ОС)
Как пользоваться в Android• Корневой ObjectGraph создается в подклассе Application
• Не получится использовать инъекцию в конструктор (объекты создаются ОС)
• Используется инъекция в поле (в Activity, Fragment, Service, View)
Как пользоваться в Android• Корневой ObjectGraph создается в подклассе Application
• Не получится использовать инъекцию в конструктор (объекты создаются ОС)
• Используется инъекция в поле (в Activity, Fragment, Service, View)
• Можно делить приложение на “области видимости” с определенным набором модулей, используя метод .plus()
Демо
Преимущества
Преимущества• Mock-‐режим для параллельной и быстрой разработки (module override + gradle flavours)
Преимущества• Mock-‐режим для параллельной и быстрой разработки (module override + gradle flavours)
• Тестовый режим для отладки и функционального тестирования (module override)
Производительность
Производительность• Генерация кода для зависимостей за счет Annotation processing
Производительность• Генерация кода для зависимостей за счет Annotation processing
• Происходит автоматически при компиляции
Производительность• Генерация кода для зависимостей за счет Annotation processing
• Происходит автоматически при компиляции• Не используется рефлексия (почти)
Производительность• Генерация кода для зависимостей за счет Annotation processing
• Происходит автоматически при компиляции• Не используется рефлексия (почти)• Удобно для отладки и для разработчиков
Будущее
Будущее• Dagger 2 (разрабатывается Google и Square)
Будущее• Dagger 2 (разрабатывается Google и Square)• Без рефлексии… совсем
Будущее• Dagger 2 (разрабатывается Google и Square)• Без рефлексии… совсем• Смерть листингу инъекций
Будущее• Dagger 2 (разрабатывается Google и Square)• Без рефлексии… совсем• Смерть листингу инъекций• http://goo.gl/7eTCJu и http://goo.gl/mW474Z
Будущее• Dagger 2 (разрабатывается Google и Square)• Без рефлексии… совсем• Смерть листингу инъекций• http://goo.gl/7eTCJu и http://goo.gl/mW474Z• Когда? Скоро :)
Будущее• Dagger 2 (разрабатывается Google и Square)• Без рефлексии… совсем• Смерть листингу инъекций• http://goo.gl/7eTCJu и http://goo.gl/mW474Z• Когда? Скоро :)
• Mortar & Flow (http://goo.gl/8tlHkz)
Будущее• Dagger 2 (разрабатывается Google и Square)• Без рефлексии… совсем• Смерть листингу инъекций• http://goo.gl/7eTCJu и http://goo.gl/mW474Z• Когда? Скоро :)
• Mortar & Flow (http://goo.gl/8tlHkz)• DI для UI в Android (Dagger-‐based)
Демо
Демо• u2020 (https://github.com/JakeWharton/u2020)
Демо• u2020 (https://github.com/JakeWharton/u2020)
• u2020-‐mortar (https://github.com/lemonlabs/u2020-‐mortar)
Демо• u2020 (https://github.com/JakeWharton/u2020)
• u2020-‐mortar (https://github.com/lemonlabs/u2020-‐mortar)
• u2020-‐mvp (https://github.com/LiveTyping/u2020-‐mvp)
Собственный опыт
Android в Омске
Android в Омске• События GDG Omsk (DevFest, хакатоны и пр.)
Android в Омске• События GDG Omsk (DevFest, хакатоны и пр.)• События +Android Developers Omsk
Android в Омске• События GDG Omsk (DevFest, хакатоны и пр.)• События +Android Developers Omsk• Доклады на IT-‐субботниках, конференциях и мини-‐конференциях :)
DevFest Omsk 2014
DevFest Omsk 2014
• 1-‐2 ноября 2014• http://gdgomsk.github.io/devfest-‐site/
Спасибо за внимание
Almaty Google Technology User Group
www.ala-‐gtug.org
Вопросы?
Almaty Google Technology User Group
Кирилл Бояршинов k.boyarshinov@ltst.ru naghtarr@gmail.com