Skip to content

DH3 Migration guide

WenChao Kong edited this page Apr 12, 2019 · 9 revisions

This page explains how to migrate a project using DH2 to DH3. If you didn't use DH2, you don't need to read it.

Migration from DH2 is not very simple, but it's doable. This migration guide explains the different step to do it.

Step 0: a project using DH2

At this stage, your app is not modularized: all your code is in a single module and DH2 worked just fine.

Here is a summary of what your project looks like at this stage:

//build.gradle

dependencies {
  implementation 'com.f2prateek.dart:dart-annotations:2.Y.Z'
  implementation 'com.f2prateek.dart:dart:2.Y.Z'
  implementation 'com.f2prateek.dart:henson:2.Y.Z'
  annotationProcessor 'com.f2prateek.dart:dart-processor:2.Y.Z'
  annotationProcessor 'com.f2prateek.dart:henson-processor:2.Y.Z'
}
class MyActivity1 extends Activity {

  @InjectExtra String foo;
}
class MyActivity2 extends Activity {

  @InjectExtra String bar;
}

Step 1: use navigation models

To prepare for the migration, you should use models for the activities you want to modularize. I.E for all activities that will be accessed from a different module.

@HensonNavigable(model=MyActivity1NavigationModel.class)
class MyActivity1 extends Activity {
}
class MyActivity1NavigationModel{
  @InjectExtra String foo;
}
//this activity will not be modularized yet
class MyActivity2 extends Activity {
  @InjectExtra String foo;
}

Step 2: introducing DH2.1

//build.gradle

dependencies {
  implementation 'com.f2prateek.dart.migration:dart-annotations:2.1.Z'
  implementation 'com.f2prateek.dart.migration:dart:2.1.Z'
  implementation 'com.f2prateek.dart.migration:henson:2.1.Z'
  annotationProcessor 'com.f2prateek.dart.migration:dart-processor:2.1.Z'
  annotationProcessor 'com.f2prateek.dart.migration:henson-processor:2.1.Z'
}

With the 2.1 migration version of DH, you got the exact same api as DH2, but we used a different groupId for the artifact so that we can use simultaneously DH2 and DH3. Also note that DH2.1 supports modularization, but it doesn't support navigation cycles. You have to switch to DH3 for this. We highly recommend not to leave your app with DH2.1 for the long term: this artifact won't be maintained anymore.

Step 3: modularize !

This is where your modularize your application and put M1 activity above in a separate module. Each module will be using DH2.1, you will need to say to henson to use 2 different package names to generate the henson class. Each module will have its own Henson class that other modules can use to navigate to them.

At this point, each activity and its navigation model are still in the same module.

//each build.gradle

dependencies {
  implementation 'com.f2prateek.dart.migration:dart-annotations:2.1.Z'
  implementation 'com.f2prateek.dart.migration:dart:2.1.Z'
  implementation 'com.f2prateek.dart.migration:henson:2.1.Z'
  annotationProcessor 'com.f2prateek.dart.migration:dart-processor:2.1.Z'
  annotationProcessor 'com.f2prateek.dart.migration:henson-processor:2.1.Z'
}

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [
                        'dart.henson.package': 'com.groupon.my_main_module_package_name',
                ]
            }
        }
    }
}

Step 4: split the navigation API

//each main module's build.gradle

dependencies {
  //following line is for for module 1 only
  api project('modulex-navigation') //expose your module navigation api here
  implementation 'com.f2prateek.dart.migration:dart-annotations:2.1.Z'
  implementation 'com.f2prateek.dart.migration:dart:2.1.Z'
  implementation 'com.f2prateek.dart.migration:henson:2.1.Z'
  annotationProcessor 'com.f2prateek.dart.migration:henson-processor:2.1.Z'
}
android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [
                        'dart.henson.package': 'com.groupon.my_main_module_package_name',
                ]
            }
        }
    }
}
//navigation module 1's build.gradle
dependencies {
  implementation 'com.f2prateek.dart.migration:dart-annotations:2.1.Z'
  implementation 'com.f2prateek.dart.migration:dart:2.1.Z'
  implementation 'com.f2prateek.dart.migration:henson:2.1.Z'
  annotationProcessor 'com.f2prateek.dart.migration:dart-processor:2.1.Z'
  annotationProcessor 'com.f2prateek.dart.migration:henson-processor:2.1.Z'
}

Step 5: migrating to DH3

If necessary, you can migrate your activities to DH3 one by one, or module by module. It's even possible to create hybrid navigation models that work for both DH2 and DH3. This is a common use case for base classes that are used by subclasses under different DH versions.

The introduction of DH3 will require:

  • using the DH3 artifacts. They are in the groupID com.f2prateek.dart.*:.*:3.Y.Z
  • a change in the import of DH classes, DH3 uses the package dart.* to avoid conflicts

Now the module 1 can fully use DH3:

//module 1's build.gradle
dependencies {
  //following line is for for module 1 only
  api project('module1-navigation') //expose your module navigation api here
  implementation 'com.f2prateek.dart.migration:dart-annotations:3.Y.Z'
  implementation 'com.f2prateek.dart.migration:dart:3.Y.Z'
  implementation 'com.f2prateek.dart.migration:henson:3.Y.Z'
  annotationProcessor 'com.f2prateek.dart.migration:henson-processor:3.Y.Z'
}
//navigation module 1's build.gradle
dependencies {
  implementation 'com.f2prateek.dart.migration:dart-annotations:3.Y.Z'
  implementation 'com.f2prateek.dart.migration:dart:3.Y.Z'
  implementation 'com.f2prateek.dart.migration:henson:3.Y.Z'
  annotationProcessor 'com.f2prateek.dart.migration:henson-processor:3.Y.Z'
}
//module 2's build.gradle
apply plugin: 'dart.henson-plugin'

buildscript {
  repostories {
     jcenter()
  }
  dependencies {
    classpath "com.f2prateek.dart:henson-plugin:3.Y.Z"
  }
}

henson {
  navigatorPackageName = "com.foo.module2"
}

dependencies {
  implementation project('module1-navigation')
  //module 2 still uses DH2 internally
  implementation 'com.f2prateek.dart.migration:dart-annotations:2.Y.Z'
  implementation 'com.f2prateek.dart.migration:dart:2.Y.Z'
  implementation 'com.f2prateek.dart.migration:henson:2.Y.Z'
  annotationProcessor 'com.f2prateek.dart.migration:henson-processor:2.Y.Z'
  //module 2 now uses DH3 to navigate to module1
  implementation 'com.f2prateek.dart.migration:dart-annotations:3.Y.Z'
  implementation 'com.f2prateek.dart.migration:dart:3.Y.Z'
  implementation 'com.f2prateek.dart.migration:henson:3.Y.Z'
  annotationProcessor 'com.f2prateek.dart.migration:henson-processor:3.Y.Z'
}

Module 2 can now use com.foo.module2.HensonNavigator to navigate to module1's activity.

Final step: remove DH2

If we want module 1 to navigate to module 2, we can simply externalize module 2 navigation api. In the case the navigation model of module 2 can be annotated:

  • either using only DH3 and module 2 can be converted to DH3
  • either using both DH2 and DH3 if required to migrate other activities inside module 2.