Android : Easier MVP with Lite-Cycle
https://www.youtube.com/watch?v=POr0uCQzof8

Android : Easier MVP with Lite-Cycle

One of the major issues that we face in our Android applications is the Life-Cycle related events, and when we use an Architecture pattern like MVP, we have to put those Life-Cycle related events in the Presenter interface so we can update our data based on the Life-Cycle, And this is where Lite-Cycle helps eliminating this boilerplate code ... let us dig into code :

The Old Way

Suppose we have an Activity that displays the current location on Map, so we have the View interface as follows :

public interface MainView {
    void updateLocationOnMap(Location location);
}

And this is our Activity that implements the View interface

public class MainActivity extends AppCompatActivity implements MainView{

    private MainPresenter presenter;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        presenter = new MainPresenterImplementer(this);
    }

    protected void onStart() {
        super.onStart();
        presenter.onStart();
    }

    protected void onStop() {
        super.onStop();
        presenter.onStop();
    }

    public void updateLocationOnMap(Location location) {
        // update location on map
    }
}

And this will be our Presenter interface

public interface MainPresenter {
    void onStart();
    void onStop();
}

And this is our Presenter implementer

public class MainPresenterImplementer implements MainPresenter {

    private final LocationRetriever locationRetriever;

    MainPresenterImplementer(MainView view) {
        locationRetriever = new LocationRetriever() {
            public void onLocationChanged(Location location) {
                view.updateLocationOnMap(location);
            }
        };
    }

    public void onStart() {
        locationRetriever.start();
    }

    public void onStop() {
        locationRetriever.stop();
    }
}

Now we have to tell the Presenter what is our Life-Cycle state so it can handle starting and stopping the Location-Retriever

The Easy Way

Instead of adding the Life-Cycle related methods in the Presenter interface, and handling invoking them manually in our Activity (or Fragment), we can use Lite-Cycle library to handle this for us, just do the following

Step 1 - update Gradle dependencies :

dependencies {
    ...
    implementation 'com.android.support:appcompat-v7:26.1.0' // must be 26+
    implementation 'com.github.Ahmed-Adel-Ismail:LiteCycle:1.1.1'
}

Step 2 - update the View interface to extend the Life-Cycle Owner interface

public interface MainView extends LifecycleOwner {
    void updateLocationOnMap(Location location);
}

Step 3 - remove Life-Cycle related methods from Presenter interface

public interface MainPresenter {    
}

Step 4 - update the Presenter Implementer with Lite-Cycle

public class MainPresenterImplementer implements MainPresenter {

    MainPresenterImplementer(MainView view) {
        
        LiteCycle.with(locationRetriever(view))
                .forLifeCycle(view)
                .onStartInvoke(locationRetriever -> locationRetriever.start())
                .onStopInvoke(locationRetriever -> locationRetriever.stop())
                .observe();
    
    }

    private LocationRetriever locationRetriever(final MainView view) {
        return new LocationRetriever() {
            public void onLocationChanged(Location location) {
                view.updateLocationOnMap(location);
            }
        };
    }
}

Now in the Presenter, the Lite-Cycle will handle invoking LocationRetriever.start() in the onStart() method, and will invoke LocationRetriever.stop() in the onStop() method ... now we only need to initialize our LocationRetriever, and this is done in the method locationRetriever(MainView)

Step 5 - update the Activity

public class MainActivity extends AppCompatActivity implements MainView{

    private MainPresenter presenter;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        presenter = new MainPresenterImplementer(this);
    }

    @Override
    public void updateLocationOnMap(Location location) {
        // update location on map
    }
}

Conclusion

As you can see, we nearly eliminated the boilerplate code, so instead of declaring methods related to Life-Cycle in our Presenter interface, and using them in our Activity or Fragment, and implementing them in our Presenter Implementer ... now all this is gone, so we have a Life-Cycle free Presenter, and a Life-Cycle free Activity ... all is handled by the Lite-Cycle library ... for more info about the Lite-Cycle library, take a look at this link :


David Howe

Coding??GreenNotes Into Existence ????

7 年

Very nice ??

回复
Michael Veroukis

Software Developer at Improving

7 年

I think you mean lightcycle. Edit: actually, never mind. That's yet another lifecycle library.

回复
Will G.

Mobile Engineer at Rally Health

7 年

Clear solution. Thanks for the info. I was doing the same approach creating a BaseActivity and implementing there the lifecycle. And every presenter can handle the lifecycle if they want to.

Mujahid Khosa

Flutter | Android | Kotlin & Java developer

7 年

why we use library if we can do this without any large effort

回复
Abozaid Ibrahim

Staff iOS Engineer | Building Scalable Mobile Apps | Mobile Lead | Mentor

7 年

Great work, we waiting for more :) We need an article clear the clean arch package organizations .. what right to do, and what's wrong,, who is the responsible for dissection of source of data the use cases or the repository

要查看或添加评论,请登录

Ahmed Adel Ismail的更多文章

  • Sharing data across multiple Mobile Squads - with examples

    Sharing data across multiple Mobile Squads - with examples

    Earlier I shared an article suggesting a solution to a common problem with teams following the "Spotify Model", which…

  • SDD - Squad Driven Design

    SDD - Squad Driven Design

    Working in multiple big teams I've found that we are always trying to apply our known best practices in software, but…

    4 条评论
  • Easier Testing with MVVM, MVI, MVP and Kotlin Multiplatform

    Easier Testing with MVVM, MVI, MVP and Kotlin Multiplatform

    Before we start, this article requires basic knowledge about the following topics : Clean Architecture Unit Testing…

    10 条评论
  • Android - A Cleaner Clean Architecture

    Android - A Cleaner Clean Architecture

    It has been a while now since Clean Architecture was out, and even many of us started embracing hexagonal (ports and…

    10 条评论
  • Beyond Functional Programming

    Beyond Functional Programming

    In the Android industry, lately functional programming was the all new stuff to learn, RxJava, Kotlin, and the whole…

    7 条评论
  • Dependency Injection in Clean Architecture

    Dependency Injection in Clean Architecture

    After Google's Opinionated Guide to Dependency Injection Video, Google made a clear statement that they want developers…

    18 条评论
  • Meta Programming in Android

    Meta Programming in Android

    Year after year we are getting rid of the boilerplate code that we need to write for small and simple tasks in Android,…

    2 条评论
  • MVI Pattern For Android In 4 Steps

    MVI Pattern For Android In 4 Steps

    Lately I wrote an article about MVI pattern, but as we are facing new problems every day and face more use-cases, we…

    7 条评论
  • Agile - Moving Fast

    Agile - Moving Fast

    We always here about Agile, and think about which methodology do we use, what practices do we have, team velocity…

    1 条评论
  • Kotlin Unit Testing with Mockito

    Kotlin Unit Testing with Mockito

    I've always believed that, if the code is designed to be tested, we wont need any testing framework or library ..

    17 条评论

社区洞察

其他会员也浏览了