Recently, the company started to promote the use of Flutter for mobile development. After more than a month of busy Dragon Boat Festival, the company is ready to launch the Flutter hybrid development iteration, writing down the hole of this process and some access processes, as well as the Flutter technology.

Since I am mainly engaged in Android development, iOS is still a rookie, so let me introduce the Android hybrid access process first

1. Create a Flutter Module

In many cases, Flutter access is based on existing mobile projects, which is weaker, less costly, and less risky than hacking into existing projects.

flutter create -t module flutter_module
Copy the code

Input in the command line interface, preferably in the same directory as the original project, the same folder. My project is basically that the original project is a Git repository, and the corresponding Flutter code is in another Git repository, so the version management is better

2. The Android system is connected

Add the code at the end of the existing setting.gradle file

setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        '/flutter_module/.android/include_flutter.groovy'
))
Copy the code

This will introduce the module resources of the corresponding Flutter. The corresponding compilation script of the Flutter framework has been written. You can read it later if you have time

Add the Flutter dependencies to the build.gradle file in the app directory

implementation project(':flutter')
Copy the code

The main dependency chains are as follows

flutter_module/.android/include_flutter.groovy ->
flutter_module/.android/Flutter/build.gradle ->
$flutterRoot/packages/flutter_tools/gradle/flutter.gradle 
Copy the code

The best way to do this is to use the following command line tool in the.Android file under the Flutter project

gradlew assembleDebug
Copy the code

Command to load the Android dependency

3. Native display of Flutter view

Button open = findViewById(R.id.openBtn);
open.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(MainActivity.this, MyFlutterActivity.class); startActivity(intent); }}); public class MyFlutterActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.activity_flutter);
        final FlutterView flutterView = Flutter.createView(
                this,
                getLifecycle(),
                "route1"); final FrameLayout layout = findViewById(R.id.flutter_container); layout.addView(flutterView); }}Copy the code

Just need addView in the Activity. It looks simple, but there are many problems. There may be a black screen during the jump process, and the reuse of the Flutter view is also a problem, as well as the corresponding Flutter jump Native interface. As a result, Google found that the FlutterBoost framework solved most of these problems.

4. Access to FlutterBoost framework

In accordance with the github.com/alibaba/flu… The official document, access found a lot of pits, do not know whether developers are disgusted to write the same document.

The access process is as follows:

4.1 The Flutter project is connected to FlutterBoost

Add the dependency to the corresponding pubspec.yaml file, which is a configuration file.

flutter_boost:
        git:
            url: 'https://github.com/alibaba/flutter_boost.git'
            ref: '0.0.411'
Copy the code

Then call Package GET, you can see in the upper right corner, and then execute gradlew assembleDebug in the. Android file to complete the dependency download.

4.2 Configuration in the main.dart file of Flutter

 @override
  void initState() { super.initState(); FlutterBoost. Singleton. RegisterPageBuilders ({/ / the name of the corresponding Page, it is best to class Http format'demoPage': (pageName, params, _) {
        returnDemoPage(); }}); FlutterBoost.handleOnStartPage(); } @override Widget build(BuildContext context) {return MaterialApp(
        title: 'Flutter Boost example',
        builder: FlutterBoost.init(postPush: _onRoutePushed),
        home: Container());
  }
 void _onRoutePushed(
  String pageName, String uniqueId, Map params, Route route, Future _) {}

Copy the code

4.3 Setting of Application in Android

@Override
  public void onCreate() {
    super.onCreate();
    initFlutterBoot();
  }

  private void initFlutterBoot() {
    FlutterBoostPlugin.init(new IPlatform() {
      @Override
      public Application getApplication() {
        return mApplication;
      }


      @Override
      public Activity getMainActivity() {// Return null to prevent the MainActivity page from moving upreturn null;
      }

      @Override
      public boolean isDebug() {
        returnAppConfig.IS_DEVELOPING; } @override public Boolean startActivity(Context Context, String URL, int requestCode) {// The callback of the Flutter jumpreturn PageRouter.openPageByUrl(context,url,requestCode);
      }

      @Override
      public Map getSettings() {
        returnnull; }}); }Copy the code

Pit 1: If getMainActivity returns MainActivity, the layout of the corresponding main page will move up, and null will be fine.

4.4 Jump of Native and Flutter interface

Native–>Fluuter

You can use PageRouter in the official Demo

public class PageRouter {

  public static final String COMMISSION_TASK_PAGE = "gamma://flutter/commissionTaskPage";
  public static final String NATIVE_CUST_INFO_PAGE_URL = "gamma://native/custInfo";

  public static boolean openPageByUrl(Context context, String url) {
    return openPageByUrl(context, url, 0, "{}");
  }

  public static boolean openPageByUrl(Context context, String url, String json) {
    return openPageByUrl(context, url, 0, json);
  }

  public static boolean openPageByUrl(Context context, String url, int requestCode) {
    return openPageByUrl(context, url, requestCode, "{}");
  }

  public static boolean openPageByUrl(Context context, String url, int requestCode, String json) {
    try {
      if(url. StartsWith (COMMISSION_TASK_PAGE)) {/ / post-loan task Intent Intent = new Intent (context, FlutterPageActivity. Class); intent.putExtra("pageName"."gamma://flutter/commissionTaskPage");
        intent.putExtra("json", json);
        context.startActivity(intent);
        return true;
      } else if(url.contains(NATIVE_CUST_INFO_PAGE_URL)) {// Open the client interface Map<String, String> params = getUrlParams(url); AppUIHelper .showCustomerInfoActivity(context, params.get("custId"));
        return true;
      }
    } catch (Throwable t) {
      return false; Private static Map getUrlParams(String URL) {Map<String, Object> Map = new HashMap<>(); url = url.replace("?".";");
    if(! url.contains(";")) {
      return map;
    }
    if (url.split(";").length > 0) {
      String[] arr = url.split(";")[1].split("&");
      for (String s : arr) {
        String key = s.split("=") [0]; String value = s.split("=") [1]; map.put(key, value); }return map;

    } else {
      returnmap; }}}Copy the code

In this way, Native pages can be set to start with Native, and Flutter to start with Flutter to make it easier to distinguish.

The corresponding FlutterPageActivity can be modified according to the official Demo.

Pit 2: The following code is best added to the FlutterPageActivity

@Override
  protected void onCreate(Bundle savedInstanceState) {
    FlutterMain.startInitialization(this);
    super.onCreate(savedInstanceState);
  }
Copy the code

Otherwise, an error will be reported

Flutter — >Native

This type of jump is similar to activities jumping to each other

 FlutterBoost.singleton.openPage(
        "${NativeUrl.NATIVE_CUST_INFO}? custId=${custId};"{});Copy the code

A jump of this type is called back to the startActivity method in the flutterBoostplugin. init method of the previous Application, and only received with PageRouter. After doing their own interface jump

5. Packing pits

The following commands need to be executed in the directories of the Flutter to release the package

flutter build apk
Copy the code

This is followed by the normal Android packaging, otherwise the packaged APK jumps to the Flutter page and flashes back