LMFR Mobility team‘s journey to open source

# ~ 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"));
public class MaterialFragment extends PandroidFragment<MaterialOpener> implements OnBackListener {

    @Override
    public void onResume(ResumeState state) {
        super.onResume(state);
        switch (state) {
            case FIRST_START:
                materialTransitionLayout.addAnimationWithViewId(opener.ivInfos, R.id.material_iv);
                materialTransitionLayout.addAnimationWithViewTag(opener.tvInfos, "coucou");
                break;
           //...
        }
    }
sendEvent(new MaterialOpener(ivInfos, tvInfos));

Kotlin dsl

adapter<String> {
    holder {
        layout = R.layout.cell_list
        itemType = 0 //your can use class has type, hashcode will be used
        binder = { view, data, index -> (view as Button).text = data }
    }
    holder {
        layout = R.layout.cell_list
        itemType = 1
        holderClass = CustomTxtHolder::class
    }
    holder {
        itemType = 2
        factory = CustomHolderFactory()
    }
    itemTypes { adapter: PandroidAdapter<String>, item: String, position: Int -> position % 3 }
}

Logger

Presenter

Templates

Security

Async

Animation

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

LMFR Mobility team‘s journey to open source - Decathlon Version

By Florian Paillard

LMFR Mobility team‘s journey to open source - Decathlon Version

With all the great resources and libraries available, building a new mobile app is easier than it’s ever been! However, when it comes to maintain a large number of applications in a growing team with differents skills and practices, it becomes more and more challenging every day. To resolve this and to go faster, Leroy Merlin decided to create tools. This talk will give you an insight into the process of creation of our open source projects : Pandroid Library and the Delivery Plugin.

  • 383