LMFR Mobility team‘s journey to open source

#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

Mobile
Team

Standard developement

Mobile developement

VS

Team diversity

LM

FR

CONTEXT

Mobility Team

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)

Mobility Team

+ 30 mobile developpers

2018

+ 40 apps & backend

AMGP

to sum up

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

  • sso
  • scanner
  • analytics
  • preferences
  • micro services - (talk Adrien Leroy)

UI Guidelines

OPEN SOURCE

Open source

  • Collaborate with others
  • Developer commitment
  • Better visibility for recruiting developers

MobileTribe

PANDROID INSIDES

Basics

Dependencies Injection

  • Dagger
  • App base component
  • Auto injection

Architecture

  • Single responsibility principle
  • Screen inter-dependencies
  • MVP pathern

Basics

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);
}

Basics

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;

//...

Basics

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(
    //...
    );

Optional libraries

Gradle dsl

pandroid{
    library('mylib') {
        libParam1 'param1'
        libParam2 'param2'
    }
}

Auto implement & bind to lifecycle

Optional libraries

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

And more

Lifecycle

LiveData

ViewModel

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

Made with Slides.com