#AdeoDevSummit
http://lmfr.io/here-is-a-shorter-url-to-access-the-game
http://lmfr.io/open-talk
http://lmfr.io/best-conf-ever
# ~ curl http://lmfr.io/florianpaillard
{
name: "Florian",
company: "Leroy Merlin France",
function: "Mobile lead developer",
beginDate: "2014"
team: "Mobility team / Colibri team",
lm-projects : {
pandroid : "open source mobile archetype",
lm-library : "lm fr archetype extension"
delivery : "open source delivery plugin",
colibri-apps: "store apps",
innovation: "htc vive, wear os prototyping ...",
...
},
other-projects : {
robolytics : "mobile analytics tag manager",
one-jitsu : "Jiu-jitsu practitioners network",
booth-app : "FatBooth, AgingBooth, ...",
...
},
links : {
twitter: "@paillard_f"
linkedin : "http://lmfr.io/florianpaillard",
robolytics : "https://robolytics.sertook.com",
perso : "http://sertook.com"
}
}
DISCLAIMER
Standard developement
Mobile developement
VS
Team diversity
3 mobile developpers
2014
3 - 5 apps
BAMBOO
WEB TEAM
Roadmap LM 2015
Gestion (backo mobile)
Vente (pyxis mobile)
Leroy Merlin France Apps (ios android)
+ 30 mobile developpers
2018
+ 40 apps & backend
AMGP
growing team
differents skills
large roadmap
no shared architecture
1 app = 1 architecture
Mobile Archetype
Abstract libraries
Navigation pattern
LMFR tools (Passport, Scanner, ...)
Design
Shared architecture
FAT
PRISONER
Solution
LM Library
Open source
Easy configuration
Optional dependencies
Performance
Security
Documentation
LM Library
Inner source
Colibri fonctionnalities
UI Guidelines
Open source
MobileTribe
PANDROID INSIDES
Dependencies Injection
Architecture
Event bus
@OnClick(R.id.event_send_to)
public void sendToSecondFragment() {
eventBusManager.send(
"My message",
"EventTag",
EventBusManager.DeliveryPolicy.AT_LEAST_ONE
);
}
@EventReceiver({"EventTag"}) //Generate provider with a tag to filter event
public void onReceiveMessage(@EventTag String tag, String msg) {
logWrapper.d(TAG, "message with tag '"+tag+"' received : " + msg);
}
LifecycleDelegate
public class IcepickLifecycleDelegate extends SimpleLifecycleDelegate<Object> {
@Override
public void onCreateView(Object target, View view, Bundle savedInstanceState) {
super.onCreateView(target, view, savedInstanceState);
Icepick.restoreInstanceState(target, savedInstanceState);
}
@Override
public void onSaveView(Object target, Bundle outState) {
if (viewExist)
Icepick.saveInstanceState(target, outState);
}
}
public class MyFragment extends PandroidFragment<FragmentOpener>{
@BindLifeCycleDelegate
IcepickLifecycleDelegate icepickDelegate;
//...
LifecycleDelegate
reviewManager.getReview("1", new NetActionDelegate<Review>(this) {
@Override
public void success(Review result) {}
@Override
public void onNetworkError(int statusCode, String errorMessage, String body, Exception e) {}
});
reviewService.getReview("1")
.rxEnqueue()
//bind observer on lifecycle thanks to RxPandroidFragment
.compose(this.<Review>bindLifecycle())
.subscribe(
//...
);
Gradle dsl
pandroid{
library('mylib') {
libParam1 'param1'
libParam2 'param2'
}
}
Auto implement & bind to lifecycle
GoogleAnalytics
FirebaseAnalytics
RxJava
Retrofit
Glide
Icepick
Crashlytics
Butterknife
SuperToasts
...
Navigation - Opener
//To handle the event
receivers.add(new FragmentEventReceiver()
.setContainerId(R.id.main_content_container)
.setAnim(FragmentEventReceiver.ANIM_MATERIAL)
.addFragment(MaterialFragment.class)
.setBackStackTag("material"));
sendEvent(new MaterialOpener(ivInfos, tvInfos));
Logger
Presenter
Templates
Security
Async
Animation
List
Storage
LiveData
Navigation
Good tools ?
DELIVERY
Make your continuous delivery faster and easier
powerful workflow
simply build and sign artifacts
archive all you need into space
THANK YOU