Recently, we have made some cross-platform migration attempts, from pure RN architecture applications to general cross-platform applications. The migration process involves cross-platform technologies such as React Native and Flutter, and also encountered many problems. This article briefly records some of them and hoping to bring a little help to the reader.

Problem And Solution

  1. The hot-reload operation can be performed normally by using flutter run in the terminal but not Android Studio.

    Solution: Set no_proxy in the shell environment. For example, append the following line to the .zshrc file.

    1
    export no_proxy="localhost,127.0.0.1"

    What a magic trick.

  2. When we press the shortcut for auto-format function in Android Studio by using Dart language, sometimes formatting will format the parameters on the same line.

    Solution: Append , to the final parameter.

  3. When we import Flutter as Module to the Android project, the right action is New Module -> import flutter model, and then, click Sync Project With Gradle Files to display the folder of Flutter.

  4. If the application has already used the AndroidX libraries, notice that the Flutter Module may use the Support libraries by default.

  5. When using Flutter, we may meet the problem Dart SDK is not configured.

    Solution: Set the Dart SDK path manually. Open File->Setting->Language & Frameworks->Dart, and then, check the enable Dart support for the project, set the child path of Flutter as SDK version. For example, we should set the SDK path as $FLUTTER\bin\cache\dart-sdk if we assume the path of Flutter is $FLUTTER.

  6. After using AndroidX, the files generated by the Flutter module need to be modified accordingly. In addition to changing the Support package to the AndroidX package, you also need to modify the Gradle version. It is recommended to use Refactor -> Migrate to AndroidX ... for migration.

    There are reference links below:

    1. AndroidX migration of Flutter.
    2. Check the setting of Android Studio
    3. Migrate to AndroidX
  7. The code generated by using Flutter can be modified locally. For example, Flutter and Flutter Boost contain Android Support libraries. Without modifying the remote repository, it can be changed to AndroidX locally.

    The migration of AndroidX is not very compatible with abnormal modules such as Flutter, even if android.useAndroidX = true and android.enableJetifier = true have been defined in gradle.properties.

  8. The Flutter module of the remote project may only have the code without the compiled .android folder and the prerequisite for the Android project to correctly recognize the Flutter module are to generate the folder, so you need to open the Flutter module and then runflutter package get.

  9. After using Flutter as an Android module for hybrid programming, the way of Flutter breakpoints are debugged has changed. When you need to run a complete project for debugging, the process should be to install the app, then close the app, perform the Flutter attach operation in the Flutter module window, and then start the app to debug the Flutter code normally.

  10. Some problem with method channel:

    Q: Can the method channel be registered repeatedly on the same Flutter page (using the same name)?
    A: Yes, and they will be the same instance.

    Q: Can the method channel be registered repeatedly on the different Flutter page (using the same name)?
    A: Yes, and they will be the same instance.

    Q: Does the method channel instantiate the same instance on different pages using the default method?
    A: No.

    Q: Will different callbacks of the same method channel affect each other?
    A: It is interesting that although it is the same method channel, callbacks will not affect each other

  11. When React Native exchanges data with native Android, the corresponding data structure is different. The map on the RN side is ReadableMap andWritableMap on Android, and the RN‘s Number type will be converted to Double when acquired on the Android side, which requires special handling. And because there is no Long type on the RN side, and the accuracy of the Long type and Double type is different, special attention is required.

Some notes about Dart

  1. Dart also have null-aware.

    • ?? equals to ?: in Kotlin
    • ??= means it can be assigned a value only when it was null, which is different from Kotlin
    • x?.p equals to x?.p in Kotlin
    • x?.m() equals to x?.m() in Kotlin
  2. Dart supports Method Cascades. .. is a cascading operator, which calls the method and discards the result, returning the original object. An example is as follows:

    1
    2
    3
    4
    mTokenTable
    ..add("aToken");
    ..add("anotherToken");
    ..add("theUmpteenthToken");

    It should be noted that, unlike chain expressions, each line of a cascade call has a characteristic semicolon of dart;