SlideShare a Scribd company logo
1 of 66
Download to read offline
RIBs
Fragments which work
Dmitry Zaytsev, Android Engineer @ Uber
1
Why Fragments?
2
3
MainActivity
4
● Encapsulation
● Lifecycle
● Navigation
Why Fragments
Fragments are great!
7
Why not Fragments?
8
● Encapsulation
● Lifecycle
● Navigation
● Scalability
Why not Fragments
10
Listeners
No compile-time safety
A dynamic type check needs to be
performed at runtime which could (and will)
lead to crashes.
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is Listener) {
listener = context
} else if (parentFragment is Listener) {
listener = parentFragment as Listener
} else {
throw RuntimeException()
}
}
Back Stack
12
FragmentA FragmentB FragmentC
Back Stack
Simple yet hard to use
Back stack works well when you don’t need
to handle back navigation yourself or use
children fragments. However, as soon as you
need to do any customization it quickly falls
apart.
// Attach Root fragment
supportFragmentManager.beginTransaction()
.apply {
add(R.id.fragmentContainer, RootFragment.newInstance(), "Root")
addToBackStack(null)
}
.commit()
// Attach Child fragment
rootFragment.childFragmentManager.beginTransaction()
.apply {
add(R.id.rootContainer, ChildFragment.newInstance(), null)
addToBackStack(null)
}
.commit()
// Press back
MainActivity
MainFragment
14
● Too many lifecycle states
● No compile-time safety when calling listeners
● Nested fragments is an afterthought
● Passing arguments
● Testability
● Non-restrictive API
● Fragments are an Android thing
● Requires glue code
Problems
16
500+Mobile Engineers who
worked on new Uber app
200+ Android Engineers who
made at least 1 commint
in Android monorepo
500+iOS Engineers who made
at least 1 commit in iOS
monorepo
Some Numbers
17
Account Info
Account Info
Balance Pill
Account Info
Balance Pill
Map
Account Info
Balance Pill
Safety Info
Map
Account Info
Balance Pill
Safety Info
Status
Map
M - V - Something
24
Naive MVP
25
Model Presenter View
Update
Read
Notify
Populate
● Works well for individual pieces
● Countless variations of the pattern
● Requires glue code
● Development slows down
● Integration points are main source of bugs
Naive MVP / MVVM
RIBs
27
Router
Interactor
Builder
28
Router
Interactor
Builder
29
Router
Interactor
Builder
30
Naive MVP
31
Model Presenter View
Update
Read
Notify
Populate
RIB
32
Interactor Presenter View
Notify
Present
Notify
Populate
Model
Update
Read
RIB
33
Interactor Presenter View
Notify
Present
Notify
Populate
Model
Update
Read
Router
Navigate
RIB
34
Interactor Presenter View
Notify
Present
Notify
Populate
Model
Update
Read
Router
Navigate
Builder
Build
Example
35
ProductList
ProductDetails
Interactor
Simple Lifecycle
Just 2 lifecycle events. Sometimes even less
than that. @Override
protected void didBecomeActive(@Nullable Bundle savedInstanceState) {
super.didBecomeActive(savedInstanceState);
// Subscribe to data source. Ready to update UI.
}
@Override
protected void willResignActive(@Nullable Bundle savedInstanceState) {
super.didBecomeActive(savedInstanceState);
// Tear down and remove subscriptions/callbacks.
}
Interactor
Business Logic
Loads data from Model layer, makes
decisions and asks Presenter to render UI.
Talks to Router to perform navigation.
@Override
protected void didBecomeActive(@Nullable Bundle savedInstanceState) {
super.didBecomeActive(savedInstanceState);
presenter.showLoading();
productApi.getProducts()
.observeOn(AndroidSchedulers.mainThread())
.as(autoDisposable(this))
.subscribe(result -> {
presenter.hideLoading();
if (result.isSuccess()) {
presenter.showProducts(result.getResult());
} else {
presenter.showError();
}
});
}
Router
Navigation
Creates other RIBs and attaches them to
view hierarchy.
void routeToProductDetails(Product product) {
ProductDetailsRouter router = productDetailsBuilder.build(
getView(),
product
);
attachChild(router);
getView().addView(router.getView());
}
Builder
Builds
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
public Router build() {
// Builds and returns a router
}
Builder
Configuration
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
@Override
protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) {
return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false);
}
public interface ParentComponent extends ProductDetailsBuilder.ParentComponent {
ProductNetworkApi productNetworkApi();
}
@dagger.Module
public abstract static class Module {
@BindsInstance
public abstract ProductDetailsInteractor.Listener productDetailsListener(
ProductListInteractor interactor
);
}
@dagger.Component(
modules = RootBuilder.Module.class,
dependencies = ParentComponent.class
)
interface Component extends InteractorBaseComponent<ProductListInteractor>,
ProductDetailsBuilder.ParentComponent {
// Dagger initialization
}
Builder
Configuration
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
@Override
protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) {
return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false);
}
public interface ParentComponent extends ProductDetailsBuilder.ParentComponent {
ProductNetworkApi productNetworkApi();
}
@dagger.Module
public abstract static class Module {
@BindsInstance
public abstract ProductDetailsInteractor.Listener productDetailsListener(
ProductListInteractor interactor
);
}
@dagger.Component(
modules = RootBuilder.Module.class,
dependencies = ParentComponent.class
)
interface Component extends InteractorBaseComponent<ProductListInteractor>,
ProductDetailsBuilder.ParentComponent {
// Dagger initialization
}
Builder
Configuration
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
@Override
protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) {
return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false);
}
public interface ParentComponent extends ProductDetailsBuilder.ParentComponent {
ProductNetworkApi productNetworkApi();
}
@dagger.Module
public abstract static class Module {
@BindsInstance
public abstract ProductDetailsInteractor.Listener productDetailsListener(
ProductListInteractor interactor
);
}
@dagger.Component(
modules = RootBuilder.Module.class,
dependencies = ParentComponent.class
)
interface Component extends InteractorBaseComponent<ProductListInteractor>,
ProductDetailsBuilder.ParentComponent {
// Dagger initialization
}
Builder
Configuration
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
@Override
protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) {
return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false);
}
public interface ParentComponent extends ProductDetailsBuilder.ParentComponent {
ProductNetworkApi productNetworkApi();
}
@dagger.Module
public abstract static class Module {
@BindsInstance
public abstract ProductDetailsInteractor.Listener productDetailsListener(
ProductListInteractor interactor
);
}
@dagger.Component(
modules = RootBuilder.Module.class,
dependencies = ParentComponent.class
)
interface Component extends InteractorBaseComponent<ProductListInteractor>,
ProductDetailsBuilder.ParentComponent {
// Dagger initialization
}
Builder
Configuration
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
@Override
protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) {
return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false);
}
public interface ParentComponent extends ProductDetailsBuilder.ParentComponent {
ProductNetworkApi productNetworkApi();
}
@dagger.Module
public abstract static class Module {
@BindsInstance
public abstract ProductDetailsInteractor.Listener productDetailsListener(
ProductListInteractor interactor
);
}
@dagger.Component(
modules = RootBuilder.Module.class,
dependencies = ParentComponent.class
)
interface Component extends InteractorBaseComponent<ProductListInteractor>,
ProductDetailsBuilder.ParentComponent {
// Dagger initialization
}
Composition
46
Account Info
Balance Pill
Safety Info
Status
Map
48
Root
Root
Logged InLogged Out
50
Root
Logged InLogged Out
Sign Up Log In
51
Root
Logged InLogged Out
MapSign Up Log In
52
Root
Logged InLogged Out
Map
Balance StatusProfile
Sign Up Log In
53
Root
Logged InLogged Out
Map
Balance StatusProfile
Payments
Sign Up Log In
Where is Activity?
54
55
Root
Logged InLogged Out
Map
Balance StatusProfile
Payments
Sign Up Log In
RootActivity
Modularization
56
57
Root
Logged InLogged Out
Map
Balance StatusProfile
Payments
Sign Up Log In
+
58
What’s the catch?
59
● Screen rotation
● Transition animations
Not included
Where to grab it?
63
uber/RIBs
64
● Good parts of MVP
● Composable
● Compile-time independent
● OS agnostic
● Scalable
● Single-Activity as a bonus
Summary
Thank you!
Time for questions
Dmitry Zaytsev, dmitry.zaytsev@uber.com
Twitter: @dizaytsev
Medium: @dmitry.zaicew

More Related Content

What's hot

Spring Boot and Microservices
Spring Boot and MicroservicesSpring Boot and Microservices
Spring Boot and Microservicesseges
 
Java EE 7 for Real Enterprise Systems
Java EE 7 for Real Enterprise SystemsJava EE 7 for Real Enterprise Systems
Java EE 7 for Real Enterprise SystemsHirofumi Iwasaki
 
Spring boot for buidling microservices
Spring boot for buidling microservicesSpring boot for buidling microservices
Spring boot for buidling microservicesNilanjan Roy
 
Spring - CDI Interop
Spring - CDI InteropSpring - CDI Interop
Spring - CDI InteropRay Ploski
 
Head toward Java 14 and Java 15 #LINE_DM
Head toward Java 14 and Java 15 #LINE_DMHead toward Java 14 and Java 15 #LINE_DM
Head toward Java 14 and Java 15 #LINE_DMYuji Kubota
 
Making React Native UI Components with Swift
Making React Native UI Components with SwiftMaking React Native UI Components with Swift
Making React Native UI Components with SwiftRay Deck
 
Springboot2 postgresql-jpa-hibernate-crud-example with test
Springboot2 postgresql-jpa-hibernate-crud-example with testSpringboot2 postgresql-jpa-hibernate-crud-example with test
Springboot2 postgresql-jpa-hibernate-crud-example with testHyukSun Kwon
 
Spring Up Your Graph
Spring Up Your GraphSpring Up Your Graph
Spring Up Your GraphVMware Tanzu
 
Enterprise Guice 20090217 Bejug
Enterprise Guice 20090217 BejugEnterprise Guice 20090217 Bejug
Enterprise Guice 20090217 Bejugrobbiev
 
Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5Arun Gupta
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot IntroductionJeevesh Pandey
 
Getting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafGetting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafMasatoshi Tada
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with SpringJoshua Long
 
Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!Stacy Devino
 
Krazykoder struts2 spring_hibernate
Krazykoder struts2 spring_hibernateKrazykoder struts2 spring_hibernate
Krazykoder struts2 spring_hibernateKrazy Koder
 
JavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopJavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopPeter Lehto
 
The Past Year in Spring for Apache Geode
The Past Year in Spring for Apache GeodeThe Past Year in Spring for Apache Geode
The Past Year in Spring for Apache GeodeVMware Tanzu
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentationguest11106b
 

What's hot (20)

Spring Boot and Microservices
Spring Boot and MicroservicesSpring Boot and Microservices
Spring Boot and Microservices
 
Java EE 7 for Real Enterprise Systems
Java EE 7 for Real Enterprise SystemsJava EE 7 for Real Enterprise Systems
Java EE 7 for Real Enterprise Systems
 
Spring boot for buidling microservices
Spring boot for buidling microservicesSpring boot for buidling microservices
Spring boot for buidling microservices
 
Spring - CDI Interop
Spring - CDI InteropSpring - CDI Interop
Spring - CDI Interop
 
Head toward Java 14 and Java 15 #LINE_DM
Head toward Java 14 and Java 15 #LINE_DMHead toward Java 14 and Java 15 #LINE_DM
Head toward Java 14 and Java 15 #LINE_DM
 
Making React Native UI Components with Swift
Making React Native UI Components with SwiftMaking React Native UI Components with Swift
Making React Native UI Components with Swift
 
Springboot2 postgresql-jpa-hibernate-crud-example with test
Springboot2 postgresql-jpa-hibernate-crud-example with testSpringboot2 postgresql-jpa-hibernate-crud-example with test
Springboot2 postgresql-jpa-hibernate-crud-example with test
 
Spring Up Your Graph
Spring Up Your GraphSpring Up Your Graph
Spring Up Your Graph
 
Enterprise Guice 20090217 Bejug
Enterprise Guice 20090217 BejugEnterprise Guice 20090217 Bejug
Enterprise Guice 20090217 Bejug
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 
Javaee6 Overview
Javaee6 OverviewJavaee6 Overview
Javaee6 Overview
 
Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot Introduction
 
Getting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafGetting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with Thymeleaf
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!
 
Krazykoder struts2 spring_hibernate
Krazykoder struts2 spring_hibernateKrazykoder struts2 spring_hibernate
Krazykoder struts2 spring_hibernate
 
JavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopJavaEE with Vaadin - Workshop
JavaEE with Vaadin - Workshop
 
The Past Year in Spring for Apache Geode
The Past Year in Spring for Apache GeodeThe Past Year in Spring for Apache Geode
The Past Year in Spring for Apache Geode
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
 

Similar to RIBs - Fragments which work

Spring training
Spring trainingSpring training
Spring trainingTechFerry
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsHassan Abid
 
Hibernate Developer Reference
Hibernate Developer ReferenceHibernate Developer Reference
Hibernate Developer ReferenceMuthuselvam RS
 
Gnizr Architecture (for developers)
Gnizr Architecture (for developers)Gnizr Architecture (for developers)
Gnizr Architecture (for developers)hchen1
 
The Best Way to Become an Android Developer Expert with Android Jetpack
The Best Way to Become an Android Developer Expert  with Android JetpackThe Best Way to Become an Android Developer Expert  with Android Jetpack
The Best Way to Become an Android Developer Expert with Android JetpackAhmad Arif Faizin
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahNick Plante
 
OttawaJS - React
OttawaJS - ReactOttawaJS - React
OttawaJS - Reactrbl002
 
From Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugFrom Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugToshiaki Maki
 
Jdk Tools For Performance Diagnostics
Jdk Tools For Performance DiagnosticsJdk Tools For Performance Diagnostics
Jdk Tools For Performance DiagnosticsDror Bereznitsky
 
Annotation-Based Spring Portlet MVC
Annotation-Based Spring Portlet MVCAnnotation-Based Spring Portlet MVC
Annotation-Based Spring Portlet MVCJohn Lewis
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For ManagersAgileThought
 
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6Saltmarch Media
 
Dropwizard Introduction
Dropwizard IntroductionDropwizard Introduction
Dropwizard IntroductionAnthony Chen
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersJiaxuan Lin
 
JSAnkara Swift v React Native
JSAnkara Swift v React NativeJSAnkara Swift v React Native
JSAnkara Swift v React NativeMuhammed Demirci
 
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKitAtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKitWojciech Seliga
 

Similar to RIBs - Fragments which work (20)

Spring training
Spring trainingSpring training
Spring training
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
 
Hibernate Developer Reference
Hibernate Developer ReferenceHibernate Developer Reference
Hibernate Developer Reference
 
Gnizr Architecture (for developers)
Gnizr Architecture (for developers)Gnizr Architecture (for developers)
Gnizr Architecture (for developers)
 
Spring boot
Spring bootSpring boot
Spring boot
 
The Best Way to Become an Android Developer Expert with Android Jetpack
The Best Way to Become an Android Developer Expert  with Android JetpackThe Best Way to Become an Android Developer Expert  with Android Jetpack
The Best Way to Become an Android Developer Expert with Android Jetpack
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and Pindah
 
OttawaJS - React
OttawaJS - ReactOttawaJS - React
OttawaJS - React
 
From Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugFrom Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsug
 
Jdk Tools For Performance Diagnostics
Jdk Tools For Performance DiagnosticsJdk Tools For Performance Diagnostics
Jdk Tools For Performance Diagnostics
 
P20CSP105-AdvJavaProg.pptx
P20CSP105-AdvJavaProg.pptxP20CSP105-AdvJavaProg.pptx
P20CSP105-AdvJavaProg.pptx
 
Annotation-Based Spring Portlet MVC
Annotation-Based Spring Portlet MVCAnnotation-Based Spring Portlet MVC
Annotation-Based Spring Portlet MVC
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For Managers
 
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
 
Dropwizard Introduction
Dropwizard IntroductionDropwizard Introduction
Dropwizard Introduction
 
Struts2 - 101
Struts2 - 101Struts2 - 101
Struts2 - 101
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for Beginners
 
JSAnkara Swift v React Native
JSAnkara Swift v React NativeJSAnkara Swift v React Native
JSAnkara Swift v React Native
 
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKitAtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
 

Recently uploaded

Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 

Recently uploaded (20)

Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 

RIBs - Fragments which work

  • 1. RIBs Fragments which work Dmitry Zaytsev, Android Engineer @ Uber 1
  • 3. 3
  • 5.
  • 6. ● Encapsulation ● Lifecycle ● Navigation Why Fragments
  • 9. ● Encapsulation ● Lifecycle ● Navigation ● Scalability Why not Fragments
  • 10. 10
  • 11. Listeners No compile-time safety A dynamic type check needs to be performed at runtime which could (and will) lead to crashes. override fun onAttach(context: Context) { super.onAttach(context) if (context is Listener) { listener = context } else if (parentFragment is Listener) { listener = parentFragment as Listener } else { throw RuntimeException() } }
  • 13. Back Stack Simple yet hard to use Back stack works well when you don’t need to handle back navigation yourself or use children fragments. However, as soon as you need to do any customization it quickly falls apart. // Attach Root fragment supportFragmentManager.beginTransaction() .apply { add(R.id.fragmentContainer, RootFragment.newInstance(), "Root") addToBackStack(null) } .commit() // Attach Child fragment rootFragment.childFragmentManager.beginTransaction() .apply { add(R.id.rootContainer, ChildFragment.newInstance(), null) addToBackStack(null) } .commit() // Press back
  • 15. ● Too many lifecycle states ● No compile-time safety when calling listeners ● Nested fragments is an afterthought ● Passing arguments ● Testability ● Non-restrictive API ● Fragments are an Android thing ● Requires glue code Problems
  • 16. 16
  • 17. 500+Mobile Engineers who worked on new Uber app 200+ Android Engineers who made at least 1 commint in Android monorepo 500+iOS Engineers who made at least 1 commit in iOS monorepo Some Numbers 17
  • 18.
  • 24. M - V - Something 24
  • 25. Naive MVP 25 Model Presenter View Update Read Notify Populate
  • 26. ● Works well for individual pieces ● Countless variations of the pattern ● Requires glue code ● Development slows down ● Integration points are main source of bugs Naive MVP / MVVM
  • 31. Naive MVP 31 Model Presenter View Update Read Notify Populate
  • 37. Interactor Simple Lifecycle Just 2 lifecycle events. Sometimes even less than that. @Override protected void didBecomeActive(@Nullable Bundle savedInstanceState) { super.didBecomeActive(savedInstanceState); // Subscribe to data source. Ready to update UI. } @Override protected void willResignActive(@Nullable Bundle savedInstanceState) { super.didBecomeActive(savedInstanceState); // Tear down and remove subscriptions/callbacks. }
  • 38. Interactor Business Logic Loads data from Model layer, makes decisions and asks Presenter to render UI. Talks to Router to perform navigation. @Override protected void didBecomeActive(@Nullable Bundle savedInstanceState) { super.didBecomeActive(savedInstanceState); presenter.showLoading(); productApi.getProducts() .observeOn(AndroidSchedulers.mainThread()) .as(autoDisposable(this)) .subscribe(result -> { presenter.hideLoading(); if (result.isSuccess()) { presenter.showProducts(result.getResult()); } else { presenter.showError(); } }); }
  • 39. Router Navigation Creates other RIBs and attaches them to view hierarchy. void routeToProductDetails(Product product) { ProductDetailsRouter router = productDetailsBuilder.build( getView(), product ); attachChild(router); getView().addView(router.getView()); }
  • 40. Builder Builds Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. public Router build() { // Builds and returns a router }
  • 41. Builder Configuration Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. @Override protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) { return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false); } public interface ParentComponent extends ProductDetailsBuilder.ParentComponent { ProductNetworkApi productNetworkApi(); } @dagger.Module public abstract static class Module { @BindsInstance public abstract ProductDetailsInteractor.Listener productDetailsListener( ProductListInteractor interactor ); } @dagger.Component( modules = RootBuilder.Module.class, dependencies = ParentComponent.class ) interface Component extends InteractorBaseComponent<ProductListInteractor>, ProductDetailsBuilder.ParentComponent { // Dagger initialization }
  • 42. Builder Configuration Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. @Override protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) { return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false); } public interface ParentComponent extends ProductDetailsBuilder.ParentComponent { ProductNetworkApi productNetworkApi(); } @dagger.Module public abstract static class Module { @BindsInstance public abstract ProductDetailsInteractor.Listener productDetailsListener( ProductListInteractor interactor ); } @dagger.Component( modules = RootBuilder.Module.class, dependencies = ParentComponent.class ) interface Component extends InteractorBaseComponent<ProductListInteractor>, ProductDetailsBuilder.ParentComponent { // Dagger initialization }
  • 43. Builder Configuration Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. @Override protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) { return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false); } public interface ParentComponent extends ProductDetailsBuilder.ParentComponent { ProductNetworkApi productNetworkApi(); } @dagger.Module public abstract static class Module { @BindsInstance public abstract ProductDetailsInteractor.Listener productDetailsListener( ProductListInteractor interactor ); } @dagger.Component( modules = RootBuilder.Module.class, dependencies = ParentComponent.class ) interface Component extends InteractorBaseComponent<ProductListInteractor>, ProductDetailsBuilder.ParentComponent { // Dagger initialization }
  • 44. Builder Configuration Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. @Override protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) { return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false); } public interface ParentComponent extends ProductDetailsBuilder.ParentComponent { ProductNetworkApi productNetworkApi(); } @dagger.Module public abstract static class Module { @BindsInstance public abstract ProductDetailsInteractor.Listener productDetailsListener( ProductListInteractor interactor ); } @dagger.Component( modules = RootBuilder.Module.class, dependencies = ParentComponent.class ) interface Component extends InteractorBaseComponent<ProductListInteractor>, ProductDetailsBuilder.ParentComponent { // Dagger initialization }
  • 45. Builder Configuration Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. @Override protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) { return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false); } public interface ParentComponent extends ProductDetailsBuilder.ParentComponent { ProductNetworkApi productNetworkApi(); } @dagger.Module public abstract static class Module { @BindsInstance public abstract ProductDetailsInteractor.Listener productDetailsListener( ProductListInteractor interactor ); } @dagger.Component( modules = RootBuilder.Module.class, dependencies = ParentComponent.class ) interface Component extends InteractorBaseComponent<ProductListInteractor>, ProductDetailsBuilder.ParentComponent { // Dagger initialization }
  • 52. 52 Root Logged InLogged Out Map Balance StatusProfile Sign Up Log In
  • 53. 53 Root Logged InLogged Out Map Balance StatusProfile Payments Sign Up Log In
  • 55. 55 Root Logged InLogged Out Map Balance StatusProfile Payments Sign Up Log In RootActivity
  • 57. 57 Root Logged InLogged Out Map Balance StatusProfile Payments Sign Up Log In
  • 58. + 58
  • 60.
  • 61.
  • 62. ● Screen rotation ● Transition animations Not included
  • 63. Where to grab it? 63
  • 65. ● Good parts of MVP ● Composable ● Compile-time independent ● OS agnostic ● Scalable ● Single-Activity as a bonus Summary
  • 66. Thank you! Time for questions Dmitry Zaytsev, dmitry.zaytsev@uber.com Twitter: @dizaytsev Medium: @dmitry.zaicew