All Projects → Syex → mvp_with_dagger

Syex / mvp_with_dagger

Licence: MIT License
How presenters survive Activity recreations on configuration changes with Dagger2

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to mvp with dagger

UTair-MVP-Sample
Android Clean Architecture + MVP Sample written in Kotlin
Stars: ✭ 27 (-6.9%)
Mutual labels:  mvp, dagger, android-architecture
Android Mvp Architecture
This repository contains a detailed sample app that implements MVP architecture using Dagger2, GreenDao, RxJava2, FastAndroidNetworking and PlaceholderView
Stars: ✭ 4,360 (+14934.48%)
Mutual labels:  mvp, dagger, android-architecture
Android Architecture
🌇该项目结合 MVP 与 Clean 架构思想,探索在 Android 项目上的最佳实践。
Stars: ✭ 112 (+286.21%)
Mutual labels:  mvp, dagger, android-architecture
Android-Learning-Resources
My curated list of resources for learning Android Development.
Stars: ✭ 24 (-17.24%)
Mutual labels:  mvp, dagger
Android Mvp Architecture
🏛 A basic sample android application to understand MVP in a very simple way. Just clone, build, run and understand MVP.
Stars: ✭ 203 (+600%)
Mutual labels:  mvp, android-architecture
Clean Architecture Android
Sample to practice Clean Architecture in android applications.
Stars: ✭ 207 (+613.79%)
Mutual labels:  mvp, android-architecture
Translateapp
📝 A translations app without interruptions, copy words and translate directly, show result by top view.
Stars: ✭ 1,722 (+5837.93%)
Mutual labels:  mvp, dagger
Preservely
Lightweight Android lib preserving objects instances during orientation changes
Stars: ✭ 22 (-24.14%)
Mutual labels:  mvp, android-architecture
Moxy
Moxy is MVP library for Android with incremental annotation processor and ktx features
Stars: ✭ 234 (+706.9%)
Mutual labels:  mvp, android-architecture
Starwars-clean
Simple project with clean architecture
Stars: ✭ 34 (+17.24%)
Mutual labels:  mvp, dagger
MVPFramework
基本框架已搭建出,后续可根据需求增加
Stars: ✭ 29 (+0%)
Mutual labels:  mvp, dagger
Android Spotify Mvp
Android Sample to explain Model View Presenter in android applications.
Stars: ✭ 184 (+534.48%)
Mutual labels:  mvp, android-architecture
Mvp Architecture Components
This is a sample project, showing the connection between Android Architecture Components and MVP pattern.
Stars: ✭ 143 (+393.1%)
Mutual labels:  mvp, android-architecture
Marvel
Marvel Characters Android Application Assigned by smava GmbH
Stars: ✭ 227 (+682.76%)
Mutual labels:  mvp, dagger
Android Base Mvp
Android Base MVP Concept with RXJava, Dagger, Event Bus, Retrofit, Glide, OkHTTP
Stars: ✭ 141 (+386.21%)
Mutual labels:  mvp, dagger
android-mvp-kotlin
使用kotlin实现Android MVP模式,使用了Dagger2、Retrofit、RxJava等
Stars: ✭ 14 (-51.72%)
Mutual labels:  mvp, dagger
DaggerAndroidMVP
Demonstrates using Dagger 2.10+ in MVP app that follows Clean Architecture, RxJava 2, RxRelay
Stars: ✭ 43 (+48.28%)
Mutual labels:  mvp, android-architecture
DaggerAutoInject
Inject automatically your Activities & Fragments, just with a simple annotation
Stars: ✭ 49 (+68.97%)
Mutual labels:  mvp, dagger
AndroidMVPArchitecture
Android MVP architecture sample project with or without RxJava and Dagger2 and Kotlin
Stars: ✭ 78 (+168.97%)
Mutual labels:  mvp, dagger
Archcomp
使用Dagger,LiveData,ViewModel,Rxjava ,Retrofit等搭建App业务模块组件化框架。并处理多个系统提供数据导致的返回数据格式不一致,More ,please readme
Stars: ✭ 127 (+337.93%)
Mutual labels:  mvp, dagger

Presenters that survive Activity configuration changes using Dagger2

Recently I was looking for an example how to make my Presenters survive an Activity recreation when a configuration change occurs. All examples that I found were using Fragments, looked way too complicated or didn't use Dagger. So I decided come up with my own solution and setup this project, so it may help other people.

The problem

My project structure was built in a way, that a Presenter was coupled to its view lifecycle. I did directly use Activities, so the Presenter was destroyed once the Activity was destroyed. That was fine for my project. Then I got to a point where I needed to run a long network operation.

On a button click the Presenter subscribed to an Observable that would perform the network operation. The Presenter updated the View with the progress. So far it worked. But on a screen rotation the Activity was recreated and therefore the Presenter, too. The new instance knew nothing about the progress.

So I wanted to change my Presenters, so they survive the Activity recreation, keep subscribed to the Observable, that performs the network task, and update the View once it is back.

The idea

Google officially suggests to use Fragment.setRetainInstance(true), but I felt like adding a Fragment only for this purpose was too much. I also read about keeping Presenters in a static Map, but couldn't find an example, also nothing that showcases this with Dagger2. My Presenters currently were injected anew every time an Activity was created, with this Map this should only happen when an Activity is really created for the first time, not on a recreation.

Note: The following section requires you to be familar with Dagger2 and MVP

The solution

First I needed to create some cache, that can be injected everywhere I needed it. I created a new class for that:

public final class PresenterCache {

    private final Map<String, BasePresenter> cachedPresenters = new ArrayMap<>();

    (...)
}

As a key I decided to simply use class names, you can use whatever you want.

I added this to my ApplicationModule, so I could get the singleton PresenterCache everywhere where it's needed

@Provides
@Singleton
PresenterCache providePresenterCache() {
  return new PresenterCache();
}

Now I could inject the PresenterCache in my BaseActivity class. I added the following method, which is called in onCreate() and checks if there is a cached presenter. If not, it creates a new one using Dagger.

private void restoreOrCreatePresenter() {
  // try to get a cached presenter
  presenter = presenterCache.getPresenter(getClass().getName());
    if (presenter == null) {
       // no cached one found, create a new one
       presenter = presenterComponent.getPresenter();
       presenterCache.putPresenter(getClass().getName(), presenter);
    }
  presenter.bindView(this);
}

So what's that presenterComponent that creates a new presenter for me? It's simply an Interface that every Dagger Component extends, that needs to provide a Presenter:

public interface PresenterComponent<T extends BasePresenter> {

    T getPresenter();
}

When Dagger builds the Components it will include a method getPresenter() now which returns you a new instance of type T.

So far, if an Activity gets recreated, it will use the cached Presenter and simply bind itself to this one, allowing the Presenter to update the view accordingly and, more important, continue e.g. network operations.

Bad side: Currently the Presenter will also be cached if the Activity is closed normally, e.g. by a back press. So let's modify BaseActivity.onStop():

@Override
protected void onStop() {
  if (!isChangingConfigurations()) {
    // activity is stopped normally, remove the cached presenter so it's not cached
    // even if activity gets killed
    presenterCache.removePresenter(presenter);
  }
  // onStop will clear view reference
  presenter.onStop(isChangingConfigurations());
}

From the documentation of isChangingConfigurations()

Check to see whether this activity is in the process of being destroyed in order to be recreated with a new configuration.

Awesome, so if we know our Activity is being stopped normally we can remove it from PresenterCache. Additionally we clear the view reference in the Presenter. We do this in onStop() as this is the last method Android guarantees us to be called. Afterwards the Activity may be killed at any given time.

There is one last modification needed. If the activity is simply stopped, e.g. because we launched a new Activity that made our Activity invisible, and now restarts, because that Activity has been closed, we want to put the presenter back to the cache and bind ourself to it:

@Override
protected void onRestart() {
  super.onRestart();
  // put presenter back to cache and re-bind view
  presenterCache.putPresenter(getClass().getName(), presenter);
  presenter.bindView(this);
  presenter.onRestart();
}

  Check out the sample for a full example.

Example

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].