Skip to content

Migration Guide (1.x.x to 2.x.x)

Alexey Ershov edited this page Feb 27, 2020 · 10 revisions

This guide will teach you how to migrate to the new version of Moxy and keep all your code working. You can also check out the full changelog.

Version 2 of Moxy introduces some breaking changes:

  1. Artifacts group name changed from com.arello-mobile to com.github.moxy-community.
  2. Package changed from com.arellomobile.mvp to moxy.
  3. No more WEAK and GLOBAL presenters. They are considered anti-patterns and removed from Moxy.
  4. No more default strategy for your View methods.
  5. MoxyReflector is not generated anymore, so moxyReflectorPackage compiler option is not needed.

Here is what you have to do to support these changes.

1. Update Gradle dependencies

If you are already using moxy-community, skip this and start from step 4.

Gradle dependencies now have different names. The minimum setup is:

implementation "com.github.moxy-community:moxy:$moxyVersion"
annotationProcessor "com.github.moxy-community:moxy-compiler:$moxyVersion"

Please refer to the readme for full artifact list and the latest Moxy version.

Moxy uses Java 8 features, so you also need to specify source and target compatibility for each module that uses Moxy:

android {
  ...
  // For Java projects
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
  // For Kotlin projects
  kotlinOptions {
    jvmTarget = "1.8"
  }
}

2. Change base package name

If you are already using moxy-community, skip this and start from step 4.

All Moxy dependencies now have different package name: instead of com.arellomobile.mvp it's just moxy. This means all your imports that looked like that:

import com.arellomobile.mvp.MvpPresenter;

now have to be changed like that:

import moxy.MvpPresenter;

The easiest way to do this is to perform a full-text search-and-replace (Ctrl+Shift+R for "Replace in Path" action in Android Studio).

3. Remove all WEAK and GLOBAL Presenters

If you are already using moxy-community, skip this and start from step 4.

If you don't have WEAK or GLOBAL Presenters in your app, also skip to step 4.

If you do have WEAK or GLOBAL Presenters... well, you should get rid of them :) These kinds of Presenters were an experiment and are now considered an anti-pattern.

GLOBAL presenter is used to share a Presenter across multiple Views. This is a bad practice because a Presenter should not be responsible for holding some global app state, it is a responsibility of a Model layer. If you want a global state, use some shared part of a Model and observe its state in regular Presenters.

WEAK presenters are referenced with WeakReference and get collected by GC. This can be the cause of an undefined behaviour and there is hardly any valid use-case for WEAK presenters which couldn't be implemented with regular presenters. You should be just fine using regular presenters instead of WEAK ones.

4. Define a Strategy for all View methods

The AddToEndStrategy used to be the default Strategy in Moxy 1. According to our users, it was a pretty controversial decision. Many users considered AddToEndSingleStrategy to be a better choice for a default Strategy, but there were adepts for almost all Strategies that Moxy had. So we decided to leave the choice of a default Strategy to you and removed the built-in default Strategy completely.

Let's sum it up:

  1. There is no more default Strategy for View methods.
  2. You have to specify a Strategy for all your View methods.

You have several options to deal with this.

Option A (recommended): support the new behaviour

You just have to specify a Strategy for each method of your View interfaces with @StateStrategyType annotation.

In case you've forgot to provide a Strategy for some method, compilation will fail with an error message telling you which View contains non-annotated methods.

To make the migration easier you can temporarily enable a migration helper with a compiler option:

enableEmptyStrategyHelper : 'true'

You can specify Moxy compiler options in your build.gradle file like that:

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [
                    // here go the options for Moxy compiler
                    enableEmptyStrategyHelper: 'true',
                    ...
                ]
            }
        }
    }
    ...
}

For a complete example check out the build.gradle file of the sample project.

What does enableEmptyStrategyHelper option do? It collects all errors associated with an empty strategy in a generated class called EmptyStrategyHelper. With this class you can easily navigate to all methods with a missing Strategy annotation.

Please remove the enableEmptyStrategyHelper option when you're done, the compilation will be a bit faster.

Option B: fall back to the old behaviour

If you like having a default Strategy for your View methods — don't worry, you can still have one!

To enable default Strategy use this compiler option:

disableEmptyStrategyCheck: 'true'

The default Strategy will be AddToEndSingleStrategy, because it is the most common strategy according to our users.

You can set the default Strategy to your own preference with another compiler option:

defaultMoxyStrategy: 'moxy.viewstate.strategy.OneExecutionStateStrategy'

Note that you have to pass a fully qualified class name of the strategy annotation class.

5. Remove moxyReflectorPackage compiler option

This is an easy one, just remove the moxyReflectorPackage compiler option. It's not needed anymore and not supported. Instead of generating MoxyReflector Moxy now uses a tiny bit of reflection. So @RegisterMoxyReflectorPackages annotation is obsolete and should be removed

That's it, you're good to go! May the Force of MVP be with you!