SlideShare a Scribd company logo
Moxy –
реализация MVP
под Android
С щепоткой магии
Шмаков Юрий
senneco@gmail.com
Чт о т а кое MVP
Основные составляющие: Model, View и Presenter
•  :Плюсы
• ,Код разбивается на мелкие независимые кусочки
• Сильно упрощается написание тестов к коду
• - ,Легко менять какую то часть не ломая при этом другую
• :Минусы
• Кода становится больше
• К этому подходу нужно привыкать
• На данный момент не сильно распространённый
MVP в Andr oi d
Позволяет снять метку GodObject с Activity:
• GUIПолное управление
• Обработка взаимодействия с пользователем
• Запуск асинхронных задач
• Обработка результата асинхронной задачи
• :Дополнительные хотелки
• View должна привязываться к уже имеющемуся Presenter при смене
конфигурации
• View всегда обязана иметь актульаное состояния
• Presenter -должен уметь жить независимо от чего то
Moxy – т е ория
View
ViewState
Presenter Model
Commands
Moxy – т е ория
View
ViewState
Presenter Model
Commands
Moxy – т е ория
View
ViewState
Presenter Model
Commands
Moxy – т е ория
View
ViewState
Presenter Model
Commands
Moxy – т е ория
ViewState
Presenter Model
Commands
View
Moxy – т е ория
ViewState
Presenter Model
Commands
View
Moxy – т е ория
ViewState
Presenter Model
Commands
View
Moxy – т е ория
ViewState
Presenter Model
Commands
View
View
Moxy – инс т руме нт ы
Moxy – MvpPr e s e nt e r
• -Содержит в себе часть бизнес логики
• -Отвечает только за одну логическую единицу бизнес логики
• Типизирован MvpView
• :Имеет полезные методы
• voidattachView(View view) и voiddetachView(View view)
• View getViewState()
• voidonFirstViewAttach()
• boolean isInRestoreState(View view)
Moxy – MvpVi e w и MvpVi e wSt a t e
• MvpView ,описывает команды которые Presenter может передать
во View
• MvpViewState ,хранит команды которые были переданы во View
• MvpViewStateимеет метод voidrestoreState(View view)
• Чаще всего не придётся самостояетльно создавать
MvpViewState
Moxy – @I nj e c t Vi e wSt a t e
• Применяется к классу MvpPresenter
• :Имеет три поведения
• Если указан параметр value, то будет использован указанный ViewState
• Если указан параметр view, то будет сгенерирован ViewState для
указанной View
• ,Если никакой параметр не указан то будет сгенерирован ViewState
для View, которой типизирован Presenter(опасайтесь типизированных
View)
• Позволяет работать с методом View getViewState()
Moxy – St a t e St r a t e gy
• Управляет нахождением команды во ViewState
• Имеет два callback- :метод
• voidbeforeApply(currentState, incomingState)
• voidafterApply(currentState, incomingState)
• Указать стратегию можно аннотацией @StateStrategyType
• @StateStrategyType :можно применить
• Ко всему интерфейсу View
• К конкретному методу интерфейса View
Moxy – MvpDe l e ga t e
• Управляет жизненным циклом Presenter
• Подставляет во View правильный экземпляр Presenter
• Отвечает за привязку View к Presenter
• Имеет несколько методов для получения состяния View:
• voidonCreate(Bundlebundle), voidonCreate() и voidonDestroy()
• voidonStart()
• voidonSaveInstanceState(BundleoutState)
• voidsetParentDelegate(MvpDelegatedelegate, StringchildId)
Moxy – @I nj e c t Pr e s e nt e r
• Применяется к Presenter-полям реализации View
• Сообщает MvpDelegate, какой Presenter нужно использовать
• Может быть двух(с половиной) :типов
• PresenterType.LOCAL
• PresenterType.GLOBAL и PresenterType.WEAK
• , !=В случае если тип PresenterType.LOCAL, MvpDelegateбудет
искать Presenter :по одному из правил
• ,По статичному тэгу указанному в параметре tag
• Используя factory, сгенерирует тэг и сам Presenter, по необходимости
Moxy – Mode l
:Содержит в себе работу с данными
• Получение данных
• Из хранилища
• Из интернате
• Хранение данных
• Обработка данных
,Самое подходящее место чтобы разгуляться DI
Moxy – приме р #1
:Задача сделать экран авторизации
• :По нажатию на кнопку входа
• Показать диалог запроса
• Начать асинхронный запрос авторизации
• :После завершения асинхронного запроса авторизации
• Скрыть диалог прогресса
• ,Если пришла ошибка то показать диалог с ошибкой
• ,Если авторизация прошла успешно то перейти на главный экран
Moxy – приме р #1
:Задача сделать экран авторизации
:Решение
•Сделать SignInView
•Сделать SignInPresenter
•Сделать SignInActivity
Moxy – приме р #1
@StateStrategyType(AddToEndSingleStrategy.class)
public interface SignInView extends MvpView
{
void toggleProgress(boolean show);
void showError(Exception exception);
void hideError();
void onSignIn();
}
public class SignInActivity extends MvpActivity implements SignInView
{
@InjectPresenter
SignInPresenter mSignInPresenter;
...
Moxy – приме р #1
@InjectViewState
public class SignInPresenter extends MvpPresenter<SignInView>
{
@Inject
Repository mRepository;
public SignInPresenter()
{
WagamamaApplication.getAppComponent().inject(this);
}
public void auth(final String login, final String password)
{
getViewState().hideError();
getViewState().toggleProgress(true);
↓↓↓
↓↓↓
mRepository.authentication().signIn(login, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<AuthenticateData>()
{
@Override
public void onCompleted()
{
getViewState().toggleProgress(false);
getViewState().onSignIn();
}
@Override
public void onError(Throwable e)
{
getViewState().toggleProgress(false);
getViewState().showError(new Exception(e));
}
});
Moxy – приме р #2
:Задача сделать аудиоплеер
•В приложении есть список треков
• Текущий трек выделяется и имеет кнопку play/ pause
• ,В приложении есть фрагмент в котором отображается
,текущий трек его состяние и кнопки play/ pauseи prev/ next
•Приложение отображает notification с отображением текущего
,трека его состяние и кнопок play/ pauseи prev/ next
Moxy – приме р #2
:Задача сделать аудиоплеер
:Решение
•Сделать PlayerView
•Сделать PlayerPresenter
•Сделать PlaylistAdapter
•Сделать PlayerFragment
•Сделать PlayerService
Moxy – приме р #2
public interface PlayerView extends MvpView
{
String PLAYER_STATE = "playerState";
@StateStrategyType(SingleStateStrategy.class)
void setCurrentTrack(TrackInfo track);
@StateStrategyType(value = PlayerStateStrategy.class, tag = PLAYER_STATE)
void playTrack();
@StateStrategyType(value = PlayerStateStrategy.class, tag = PLAYER_STATE)
void pauseTrack();
}
Moxy – приме р #2
public class PlayerStateStrategy implements StateStrategy
{
@Override
public <View extends MvpView> void beforeApply(List<Pair<ViewCommand<View>, Object>> currentState,
Pair<ViewCommand<View>, Object> incomingState)
{
for (Pair<ViewCommand<View>, Object> viewCommand : currentState)
{
if (viewCommand.first.getTag().equals(PlayerView.PLAYER_STATE))
{
currentState.remove(viewCommand);
break;
}
}
currentState.add(incomingState);
}
@Override
public <View extends MvpView> void afterApply(List<Pair<ViewCommand<View>, Object>> currentState,
Pair<ViewCommand<View>, Object> incomingState)
{
}
}
Moxy – приме р #2
public class PlayerPresenter extends MvpPresenter<PlayerView>
{
public static final String TAG = "player";
public PlayerPresenter()
{
super();
PlayerApp.get().getBus().register(this);
}
@Subscribe
public void playTrack(PlayTrackEvent event)
{
playTrack(event.getTrack());
}
public void playTrack(TrackInfo trackInfo)
{
getViewState().setCurrentTrack(trackInfo);
getViewState().playTrack();
}
↓↓↓
↓↓↓
public void playTrack()
{
getViewState().playTrack();
}
public void pauseTrack()
{
getViewState().pauseTrack();
}
@Override
public void onDestroy()
{
super.onDestroy();
PlayerApp.get().getBus().unregister(this);
}
}
Moxy – приме р #2
public class PlaylistAdapter extends BaseAdapter implements PlayerView
{
@InjectPresenter(type = PresenterType.WEAK, tag = PlayerPresenter.TAG)
PlayerPresenter mPlayerPresenter;
public PlaylistAdapter(MvpDelegate<?> parentDelegate)
{
MvpDelegate<PlaylistAdapter> delegate = new MvpDelegate<>(this);
delegate.setParentDelegate(parentDelegate, "");
delegate.onCreate();
}
...
public class MainActivity extends MvpActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PlaylistAdapter adapter = new PlaylistAdapter(getMvpDelegate());
...
Moxy – приме р #2
public class PlayerService extends Service implements PlayerView
{
@InjectPresenter(type = PresenterType.WEAK, tag = PlayerPresenter.TAG)
PlayerPresenter mPlayerPresenter;
private MvpDelegate<PlayerService> mDelegate;
@Override
public void onCreate()
{
super.onCreate();
mDelegate = new MvpDelegate<>(this);
mDelegate.onCreate(null);
mDelegate.onStart();
}
...
@Override
public void onDestroy()
{
super.onDestroy();
mDelegate.onDestroy();
...
Moxy – приме р #2
public class PlayerFragment extends MvpFragment implements PlayerView
{
@InjectPresenter(type = PresenterType.WEAK, tag = PlayerPresenter.TAG)
PlayerPresenter mPlayerPresenter;
...
Moxy – конкуре нт ы
главный конкурент– одинMosby с неудобным ViewState
Moxy – ит ог о
• :Что имеем
• Решены проблемы с жизненным циклом
• -Всегда отображается актуальное состояние бизнес логики
• Codegeneration
• :Важные советы
• Не меняйте View командой из View
• Добавляйте и удаляйте элементы View только через Presenter
• ,Если не компилится внимательно вчитайтесь в описание ошибки
• Используйте DI для связки Presenter↔Model
• MVP != инструмент
На почит а т ь
• Moxy — MVP Androidреализация под с щепоткой магии
• AndroidApplication Architecture(AndroidDev Summit 2015)
• AndroidTestingCodelab
• Nucleus
• Mosby
• OldMosby
• STINSON'SPLAYBOOK FORMOSBY 
• AndroidReactiveMVP: практика
• AndrtoidClean Architecture 
• . Speaker Clean Architecture MVPАлексей Макаров и  
• Mosby issues 85 

More Related Content

What's hot

Модульная структура
Модульная структураМодульная структура
Модульная структура
Denis Tsvettsih
 
Школа-студия разработки приложений для iOS. 2 лекция. MVC, View, Controllers
Школа-студия разработки приложений для iOS. 2 лекция. MVC, View, ControllersШкола-студия разработки приложений для iOS. 2 лекция. MVC, View, Controllers
Школа-студия разработки приложений для iOS. 2 лекция. MVC, View, ControllersГлеб Тарасов
 
Как приручить реактивное программирование в XAML приложениях
Как приручить реактивное программирование в XAML приложенияхКак приручить реактивное программирование в XAML приложениях
Как приручить реактивное программирование в XAML приложениях
Denis Tsvettsih
 
Как приручить реактивное программирование
Как приручить реактивное программированиеКак приручить реактивное программирование
Как приручить реактивное программирование
Denis Tsvettsih
 
C# Web. Занятие 11.
C# Web. Занятие 11.C# Web. Занятие 11.
C# Web. Занятие 11.
Igor Shkulipa
 
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOSКурсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOSГлеб Тарасов
 
Олексій Стульніков “WinAppDriver – автоматизація Desktop ніколи не була такою...
Олексій Стульніков “WinAppDriver – автоматизація Desktop ніколи не була такою...Олексій Стульніков “WinAppDriver – автоматизація Desktop ніколи не була такою...
Олексій Стульніков “WinAppDriver – автоматизація Desktop ніколи не була такою...
Dakiry
 
Антон Валюх - Использование паттерна Mvvm в android
Антон Валюх - Использование паттерна Mvvm в androidАнтон Валюх - Использование паттерна Mvvm в android
Антон Валюх - Использование паттерна Mvvm в android
DataArt
 
AndroidMVPHelper
AndroidMVPHelperAndroidMVPHelper
AndroidMVPHelper
DataArt
 
Dependency Injection на примере Unity и NInject
Dependency Injection на примере Unity и NInjectDependency Injection на примере Unity и NInject
Dependency Injection на примере Unity и NInject
akrakovetsky
 
Автоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows PhoneАвтоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows Phone
CodeFest
 
55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)
55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)
55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)
Ontico
 
Build a VR Pawn with Unreal Engine Luis Cataldi Russian
Build a VR Pawn with Unreal Engine   Luis Cataldi RussianBuild a VR Pawn with Unreal Engine   Luis Cataldi Russian
Build a VR Pawn with Unreal Engine Luis Cataldi Russian
Unreal Engine
 
Рендеринг может больше: vue.js vs React, Андрей Солодовников
Рендеринг может больше: vue.js vs React, Андрей СолодовниковРендеринг может больше: vue.js vs React, Андрей Солодовников
Рендеринг может больше: vue.js vs React, Андрей Солодовников
DevDay
 
Разработка Web-приложений на Angular JS. Архитектурные семинары Softengi
Разработка Web-приложений на Angular JS. Архитектурные семинары SoftengiРазработка Web-приложений на Angular JS. Архитектурные семинары Softengi
Разработка Web-приложений на Angular JS. Архитектурные семинары Softengi
Softengi
 
Модульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETМодульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NET
Dev2Dev
 
Gwt jug basic
Gwt jug basicGwt jug basic
Gwt jug basic
Alex Tumanoff
 
Алексей Андросов - Debugger: Отладка кода
Алексей Андросов - Debugger: Отладка кодаАлексей Андросов - Debugger: Отладка кода
Алексей Андросов - Debugger: Отладка кода
Yandex
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.
Igor Shkulipa
 
Windows 10 SDK
Windows 10 SDKWindows 10 SDK
Windows 10 SDK
Mykyta Bondarenko
 

What's hot (20)

Модульная структура
Модульная структураМодульная структура
Модульная структура
 
Школа-студия разработки приложений для iOS. 2 лекция. MVC, View, Controllers
Школа-студия разработки приложений для iOS. 2 лекция. MVC, View, ControllersШкола-студия разработки приложений для iOS. 2 лекция. MVC, View, Controllers
Школа-студия разработки приложений для iOS. 2 лекция. MVC, View, Controllers
 
Как приручить реактивное программирование в XAML приложениях
Как приручить реактивное программирование в XAML приложенияхКак приручить реактивное программирование в XAML приложениях
Как приручить реактивное программирование в XAML приложениях
 
Как приручить реактивное программирование
Как приручить реактивное программированиеКак приручить реактивное программирование
Как приручить реактивное программирование
 
C# Web. Занятие 11.
C# Web. Занятие 11.C# Web. Занятие 11.
C# Web. Занятие 11.
 
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOSКурсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
 
Олексій Стульніков “WinAppDriver – автоматизація Desktop ніколи не була такою...
Олексій Стульніков “WinAppDriver – автоматизація Desktop ніколи не була такою...Олексій Стульніков “WinAppDriver – автоматизація Desktop ніколи не була такою...
Олексій Стульніков “WinAppDriver – автоматизація Desktop ніколи не була такою...
 
Антон Валюх - Использование паттерна Mvvm в android
Антон Валюх - Использование паттерна Mvvm в androidАнтон Валюх - Использование паттерна Mvvm в android
Антон Валюх - Использование паттерна Mvvm в android
 
AndroidMVPHelper
AndroidMVPHelperAndroidMVPHelper
AndroidMVPHelper
 
Dependency Injection на примере Unity и NInject
Dependency Injection на примере Unity и NInjectDependency Injection на примере Unity и NInject
Dependency Injection на примере Unity и NInject
 
Автоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows PhoneАвтоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows Phone
 
55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)
55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)
55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)
 
Build a VR Pawn with Unreal Engine Luis Cataldi Russian
Build a VR Pawn with Unreal Engine   Luis Cataldi RussianBuild a VR Pawn with Unreal Engine   Luis Cataldi Russian
Build a VR Pawn with Unreal Engine Luis Cataldi Russian
 
Рендеринг может больше: vue.js vs React, Андрей Солодовников
Рендеринг может больше: vue.js vs React, Андрей СолодовниковРендеринг может больше: vue.js vs React, Андрей Солодовников
Рендеринг может больше: vue.js vs React, Андрей Солодовников
 
Разработка Web-приложений на Angular JS. Архитектурные семинары Softengi
Разработка Web-приложений на Angular JS. Архитектурные семинары SoftengiРазработка Web-приложений на Angular JS. Архитектурные семинары Softengi
Разработка Web-приложений на Angular JS. Архитектурные семинары Softengi
 
Модульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETМодульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NET
 
Gwt jug basic
Gwt jug basicGwt jug basic
Gwt jug basic
 
Алексей Андросов - Debugger: Отладка кода
Алексей Андросов - Debugger: Отладка кодаАлексей Андросов - Debugger: Отладка кода
Алексей Андросов - Debugger: Отладка кода
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.
 
Windows 10 SDK
Windows 10 SDKWindows 10 SDK
Windows 10 SDK
 

Similar to Moxy – реализация MVP под Android. С щепоткой магии

iOS and Android Mobile Test Automation
iOS and Android Mobile Test AutomationiOS and Android Mobile Test Automation
iOS and Android Mobile Test Automation
Andrii Dzynia
 
Mobile automation uamobile
Mobile automation uamobileMobile automation uamobile
Mobile automation uamobileUA Mobile
 
MWWM
MWWMMWWM
MWWM
Cleveroad
 
Appium для народа
Appium для народаAppium для народа
Appium для народа
SQALab
 
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Sigma Software
 
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCАрхитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
DevDay
 
Enterprise flex pure mvc.v4
Enterprise flex pure mvc.v4Enterprise flex pure mvc.v4
Enterprise flex pure mvc.v4
Sergiy Shychynov
 
Навигация в Android без боли и слез
Навигация в Android без боли и слезНавигация в Android без боли и слез
Навигация в Android без боли и слез
MobileUp
 
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программистаРазработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
DotNetConf
 
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программистаРазработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
Denis Tsvettsih
 
Живые обои для Android. Как создать. Тонкости. Продвижение
Живые обои для Android. Как создать. Тонкости. ПродвижениеЖивые обои для Android. Как создать. Тонкости. Продвижение
Живые обои для Android. Как создать. Тонкости. Продвижение
Sergey Mikhaylov
 
Automation Functional Testing in Agile Projects
Automation Functional Testing in Agile ProjectsAutomation Functional Testing in Agile Projects
Automation Functional Testing in Agile Projects
Andrey Rebrov
 
Фундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоФундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоStanfy
 
М. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с CodeceptionМ. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с CodeceptionAlbina Tiupa
 
Михаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с CodeceptionМихаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с CodeceptionAlbina Tiupa
 
Референсная архитектура приложения на ASP.NET MVC
Референсная архитектура приложения на ASP.NET MVCРеференсная архитектура приложения на ASP.NET MVC
Референсная архитектура приложения на ASP.NET MVCAndrew Mayorov
 
Enterprise flex pure mvc, slides, russian
Enterprise flex pure mvc, slides, russianEnterprise flex pure mvc, slides, russian
Enterprise flex pure mvc, slides, russian
Sergiy Shychynov
 
Где кончается react native? / Павел Кондратенко (Rambler&Co)
Где кончается react native? / Павел Кондратенко (Rambler&Co)Где кончается react native? / Павел Кондратенко (Rambler&Co)
Где кончается react native? / Павел Кондратенко (Rambler&Co)
Ontico
 
Изоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесьИзоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесь
CodeFest
 
E2E-тестирование мобильных приложений
E2E-тестирование мобильных приложенийE2E-тестирование мобильных приложений
E2E-тестирование мобильных приложений
MoscowJS
 

Similar to Moxy – реализация MVP под Android. С щепоткой магии (20)

iOS and Android Mobile Test Automation
iOS and Android Mobile Test AutomationiOS and Android Mobile Test Automation
iOS and Android Mobile Test Automation
 
Mobile automation uamobile
Mobile automation uamobileMobile automation uamobile
Mobile automation uamobile
 
MWWM
MWWMMWWM
MWWM
 
Appium для народа
Appium для народаAppium для народа
Appium для народа
 
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
 
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCАрхитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
 
Enterprise flex pure mvc.v4
Enterprise flex pure mvc.v4Enterprise flex pure mvc.v4
Enterprise flex pure mvc.v4
 
Навигация в Android без боли и слез
Навигация в Android без боли и слезНавигация в Android без боли и слез
Навигация в Android без боли и слез
 
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программистаРазработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
 
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программистаРазработка Windows 8 приложений глазами WPF/Silverlight программиста
Разработка Windows 8 приложений глазами WPF/Silverlight программиста
 
Живые обои для Android. Как создать. Тонкости. Продвижение
Живые обои для Android. Как создать. Тонкости. ПродвижениеЖивые обои для Android. Как создать. Тонкости. Продвижение
Живые обои для Android. Как создать. Тонкости. Продвижение
 
Automation Functional Testing in Agile Projects
Automation Functional Testing in Agile ProjectsAutomation Functional Testing in Agile Projects
Automation Functional Testing in Agile Projects
 
Фундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоФундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел Тайкало
 
М. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с CodeceptionМ. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с Codeception
 
Михаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с CodeceptionМихаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с Codeception
 
Референсная архитектура приложения на ASP.NET MVC
Референсная архитектура приложения на ASP.NET MVCРеференсная архитектура приложения на ASP.NET MVC
Референсная архитектура приложения на ASP.NET MVC
 
Enterprise flex pure mvc, slides, russian
Enterprise flex pure mvc, slides, russianEnterprise flex pure mvc, slides, russian
Enterprise flex pure mvc, slides, russian
 
Где кончается react native? / Павел Кондратенко (Rambler&Co)
Где кончается react native? / Павел Кондратенко (Rambler&Co)Где кончается react native? / Павел Кондратенко (Rambler&Co)
Где кончается react native? / Павел Кондратенко (Rambler&Co)
 
Изоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесьИзоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесь
 
E2E-тестирование мобильных приложений
E2E-тестирование мобильных приложенийE2E-тестирование мобильных приложений
E2E-тестирование мобильных приложений
 

Moxy – реализация MVP под Android. С щепоткой магии

  • 1. Moxy – реализация MVP под Android С щепоткой магии Шмаков Юрий senneco@gmail.com
  • 2. Чт о т а кое MVP Основные составляющие: Model, View и Presenter •  :Плюсы • ,Код разбивается на мелкие независимые кусочки • Сильно упрощается написание тестов к коду • - ,Легко менять какую то часть не ломая при этом другую • :Минусы • Кода становится больше • К этому подходу нужно привыкать • На данный момент не сильно распространённый
  • 3. MVP в Andr oi d Позволяет снять метку GodObject с Activity: • GUIПолное управление • Обработка взаимодействия с пользователем • Запуск асинхронных задач • Обработка результата асинхронной задачи • :Дополнительные хотелки • View должна привязываться к уже имеющемуся Presenter при смене конфигурации • View всегда обязана иметь актульаное состояния • Presenter -должен уметь жить независимо от чего то
  • 4. Moxy – т е ория View ViewState Presenter Model Commands
  • 5. Moxy – т е ория View ViewState Presenter Model Commands
  • 6. Moxy – т е ория View ViewState Presenter Model Commands
  • 7. Moxy – т е ория View ViewState Presenter Model Commands
  • 8. Moxy – т е ория ViewState Presenter Model Commands View
  • 9. Moxy – т е ория ViewState Presenter Model Commands View
  • 10. Moxy – т е ория ViewState Presenter Model Commands View
  • 11. Moxy – т е ория ViewState Presenter Model Commands View View
  • 12. Moxy – инс т руме нт ы
  • 13. Moxy – MvpPr e s e nt e r • -Содержит в себе часть бизнес логики • -Отвечает только за одну логическую единицу бизнес логики • Типизирован MvpView • :Имеет полезные методы • voidattachView(View view) и voiddetachView(View view) • View getViewState() • voidonFirstViewAttach() • boolean isInRestoreState(View view)
  • 14. Moxy – MvpVi e w и MvpVi e wSt a t e • MvpView ,описывает команды которые Presenter может передать во View • MvpViewState ,хранит команды которые были переданы во View • MvpViewStateимеет метод voidrestoreState(View view) • Чаще всего не придётся самостояетльно создавать MvpViewState
  • 15. Moxy – @I nj e c t Vi e wSt a t e • Применяется к классу MvpPresenter • :Имеет три поведения • Если указан параметр value, то будет использован указанный ViewState • Если указан параметр view, то будет сгенерирован ViewState для указанной View • ,Если никакой параметр не указан то будет сгенерирован ViewState для View, которой типизирован Presenter(опасайтесь типизированных View) • Позволяет работать с методом View getViewState()
  • 16. Moxy – St a t e St r a t e gy • Управляет нахождением команды во ViewState • Имеет два callback- :метод • voidbeforeApply(currentState, incomingState) • voidafterApply(currentState, incomingState) • Указать стратегию можно аннотацией @StateStrategyType • @StateStrategyType :можно применить • Ко всему интерфейсу View • К конкретному методу интерфейса View
  • 17. Moxy – MvpDe l e ga t e • Управляет жизненным циклом Presenter • Подставляет во View правильный экземпляр Presenter • Отвечает за привязку View к Presenter • Имеет несколько методов для получения состяния View: • voidonCreate(Bundlebundle), voidonCreate() и voidonDestroy() • voidonStart() • voidonSaveInstanceState(BundleoutState) • voidsetParentDelegate(MvpDelegatedelegate, StringchildId)
  • 18. Moxy – @I nj e c t Pr e s e nt e r • Применяется к Presenter-полям реализации View • Сообщает MvpDelegate, какой Presenter нужно использовать • Может быть двух(с половиной) :типов • PresenterType.LOCAL • PresenterType.GLOBAL и PresenterType.WEAK • , !=В случае если тип PresenterType.LOCAL, MvpDelegateбудет искать Presenter :по одному из правил • ,По статичному тэгу указанному в параметре tag • Используя factory, сгенерирует тэг и сам Presenter, по необходимости
  • 19. Moxy – Mode l :Содержит в себе работу с данными • Получение данных • Из хранилища • Из интернате • Хранение данных • Обработка данных ,Самое подходящее место чтобы разгуляться DI
  • 20. Moxy – приме р #1 :Задача сделать экран авторизации • :По нажатию на кнопку входа • Показать диалог запроса • Начать асинхронный запрос авторизации • :После завершения асинхронного запроса авторизации • Скрыть диалог прогресса • ,Если пришла ошибка то показать диалог с ошибкой • ,Если авторизация прошла успешно то перейти на главный экран
  • 21. Moxy – приме р #1 :Задача сделать экран авторизации :Решение •Сделать SignInView •Сделать SignInPresenter •Сделать SignInActivity
  • 22. Moxy – приме р #1 @StateStrategyType(AddToEndSingleStrategy.class) public interface SignInView extends MvpView { void toggleProgress(boolean show); void showError(Exception exception); void hideError(); void onSignIn(); } public class SignInActivity extends MvpActivity implements SignInView { @InjectPresenter SignInPresenter mSignInPresenter; ...
  • 23. Moxy – приме р #1 @InjectViewState public class SignInPresenter extends MvpPresenter<SignInView> { @Inject Repository mRepository; public SignInPresenter() { WagamamaApplication.getAppComponent().inject(this); } public void auth(final String login, final String password) { getViewState().hideError(); getViewState().toggleProgress(true); ↓↓↓ ↓↓↓ mRepository.authentication().signIn(login, password) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<AuthenticateData>() { @Override public void onCompleted() { getViewState().toggleProgress(false); getViewState().onSignIn(); } @Override public void onError(Throwable e) { getViewState().toggleProgress(false); getViewState().showError(new Exception(e)); } });
  • 24. Moxy – приме р #2 :Задача сделать аудиоплеер •В приложении есть список треков • Текущий трек выделяется и имеет кнопку play/ pause • ,В приложении есть фрагмент в котором отображается ,текущий трек его состяние и кнопки play/ pauseи prev/ next •Приложение отображает notification с отображением текущего ,трека его состяние и кнопок play/ pauseи prev/ next
  • 25. Moxy – приме р #2 :Задача сделать аудиоплеер :Решение •Сделать PlayerView •Сделать PlayerPresenter •Сделать PlaylistAdapter •Сделать PlayerFragment •Сделать PlayerService
  • 26. Moxy – приме р #2 public interface PlayerView extends MvpView { String PLAYER_STATE = "playerState"; @StateStrategyType(SingleStateStrategy.class) void setCurrentTrack(TrackInfo track); @StateStrategyType(value = PlayerStateStrategy.class, tag = PLAYER_STATE) void playTrack(); @StateStrategyType(value = PlayerStateStrategy.class, tag = PLAYER_STATE) void pauseTrack(); }
  • 27. Moxy – приме р #2 public class PlayerStateStrategy implements StateStrategy { @Override public <View extends MvpView> void beforeApply(List<Pair<ViewCommand<View>, Object>> currentState, Pair<ViewCommand<View>, Object> incomingState) { for (Pair<ViewCommand<View>, Object> viewCommand : currentState) { if (viewCommand.first.getTag().equals(PlayerView.PLAYER_STATE)) { currentState.remove(viewCommand); break; } } currentState.add(incomingState); } @Override public <View extends MvpView> void afterApply(List<Pair<ViewCommand<View>, Object>> currentState, Pair<ViewCommand<View>, Object> incomingState) { } }
  • 28. Moxy – приме р #2 public class PlayerPresenter extends MvpPresenter<PlayerView> { public static final String TAG = "player"; public PlayerPresenter() { super(); PlayerApp.get().getBus().register(this); } @Subscribe public void playTrack(PlayTrackEvent event) { playTrack(event.getTrack()); } public void playTrack(TrackInfo trackInfo) { getViewState().setCurrentTrack(trackInfo); getViewState().playTrack(); } ↓↓↓ ↓↓↓ public void playTrack() { getViewState().playTrack(); } public void pauseTrack() { getViewState().pauseTrack(); } @Override public void onDestroy() { super.onDestroy(); PlayerApp.get().getBus().unregister(this); } }
  • 29. Moxy – приме р #2 public class PlaylistAdapter extends BaseAdapter implements PlayerView { @InjectPresenter(type = PresenterType.WEAK, tag = PlayerPresenter.TAG) PlayerPresenter mPlayerPresenter; public PlaylistAdapter(MvpDelegate<?> parentDelegate) { MvpDelegate<PlaylistAdapter> delegate = new MvpDelegate<>(this); delegate.setParentDelegate(parentDelegate, ""); delegate.onCreate(); } ... public class MainActivity extends MvpActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); PlaylistAdapter adapter = new PlaylistAdapter(getMvpDelegate()); ...
  • 30. Moxy – приме р #2 public class PlayerService extends Service implements PlayerView { @InjectPresenter(type = PresenterType.WEAK, tag = PlayerPresenter.TAG) PlayerPresenter mPlayerPresenter; private MvpDelegate<PlayerService> mDelegate; @Override public void onCreate() { super.onCreate(); mDelegate = new MvpDelegate<>(this); mDelegate.onCreate(null); mDelegate.onStart(); } ... @Override public void onDestroy() { super.onDestroy(); mDelegate.onDestroy(); ...
  • 31. Moxy – приме р #2 public class PlayerFragment extends MvpFragment implements PlayerView { @InjectPresenter(type = PresenterType.WEAK, tag = PlayerPresenter.TAG) PlayerPresenter mPlayerPresenter; ...
  • 32. Moxy – конкуре нт ы главный конкурент– одинMosby с неудобным ViewState
  • 33. Moxy – ит ог о • :Что имеем • Решены проблемы с жизненным циклом • -Всегда отображается актуальное состояние бизнес логики • Codegeneration • :Важные советы • Не меняйте View командой из View • Добавляйте и удаляйте элементы View только через Presenter • ,Если не компилится внимательно вчитайтесь в описание ошибки • Используйте DI для связки Presenter↔Model • MVP != инструмент
  • 34. На почит а т ь • Moxy — MVP Androidреализация под с щепоткой магии • AndroidApplication Architecture(AndroidDev Summit 2015) • AndroidTestingCodelab • Nucleus • Mosby • OldMosby • STINSON'SPLAYBOOK FORMOSBY  • AndroidReactiveMVP: практика • AndrtoidClean Architecture  • . Speaker Clean Architecture MVPАлексей Макаров и   • Mosby issues 85