Google模式Android混合Flutter 开发

1,754 阅读3分钟

提示:

考虑使用abiFilters Android Gradle插件API来限制APK中支持的架构。这样做可以避免丢失libflutter.so运行时崩溃

android {
  //...
  defaultConfig {
    ndk {  
      // Filter for architectures supported by Flutter.  
      abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
    }
  }
}

Flutter引擎具有x86x86_64版本。在调试实时(JIT)模式下使用仿真器时,Flutter模块仍可正常运行。

1、创建混合开发工程

Step1: 创建原生安卓项目

注意:Flutter Android引擎使用Java 8功能。

在尝试将Flutter模块项目连接到主机Android应用之前,请确保您的主机Android应用在您的应用build.gradle文件中的android { } 块下声明了以下源兼容性

android {
  //...
  compileOptions {
    sourceCompatibility 1.8
    targetCompatibility 1.8
  }
}
Step 2: 创建Flutter module模版
flutter create -t module flutter_module // 这里module名称可以修改,相应的下个步骤中module名称改成统一的

复制代码这个时候会看到project中新增加了一个flutter_module,其中包含了.android,.ios和关键的include_flutter.groovy文件

Step 3: 将Flutter添加到现有工程中

在android工程的根目录的settings.gradle中添加,这里有坑?

include ':app'                                     // assumed existing content
setBinding(new Binding([gradle: this]))                                 // new
evaluate(new File(                                                      // new
  settingsDir.parentFile,                                               // new
  //这里会遇到坑 需要在前面加上你的工程名称 比如我的工程名称 FlutterHybridDemo
  //'FlutterHybridDemo/flutter_module/.android/include_flutter.groovy' 
  '你的工程全名/flutter_module/.android/include_flutter.groovy'            // new
)) 

在app的build.gradle中添加依赖

dependencies {
  implementation project(':flutter')

点击运行又会有坑说SDK版本过低 必须大于等16,

ERROR: Manifest merger failed : uses-sdk:minSdkVersion 15 cannot be smaller than version 16 declared in library [:flutter] D:\project\FlutterHybridDemo\flutter_module\.android\Flutter\build\intermediates\library_manifest\debug\AndroidManifest.xml as the library might be using APIs not available in 15
	Suggestion: use a compatible library with a minSdk of at most 15,
		or increase this project's minSdk version to at least 16,
		or use tools:overrideLibrary="com.example.flutter_module" to force usage (may lead to runtime failures)

两个地方的最小SDK 都要修改

再次运行又报错,最小支持SDK为24

Default interface methods are only supported starting with Android N (--min-api 24): void androidx.lifecycle.DefaultLifecycleObserver.onCreate(androidx.lifecycle.LifecycleOwner)

于是把最小支持SDK 改为24(同理两个地方最小SDK 都要修改)

2、将Flutter屏幕添加到Android应用

step1:将FlutterActivity添加到AndroidManifest.xml

Flutter提供FlutterActivity在Android应用程序中显示Flutter体验功能,FlutterActivity必须在AndroidManifest.xml注册

<!--//@style/LaunchTheme可以使用任何要应用于的Android主题替换-->
<activity
  android:name="io.flutter.embedding.android.FlutterActivity"
  android:theme="@style/AppTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
  android:hardwareAccelerated="true"
  android:windowSoftInputMode="adjustResize"
  />

step2:启动FlutterActivity
方式一:

添加按钮点击跳转到FlutterActivity

myButton.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
    startActivity(
      FlutterActivity.createDefaultIntent(currentActivity)
    );
  }
});

Dart入口点称为main(),初始Flutter路线为“ /”。无法使用更改Dart入口点Intent,但可以使用更改初始路线Intent。以下示例演示了如何启动 FlutterActivity最初在Flutter中呈现自定义路线的。

myButton.addOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
    startActivity(
      FlutterActivity
        .withNewEngine()
        .initialRoute("/route")//替换"/route"为所需的初始路线。
        .build(currentActivity)
      );
  }
});
方式二:

使用缓存的FlutterEngine

每个默认FlutterActivity创建自己FlutterEngine的。每个 FlutterEngine都有不平凡的预热时间。这意味着在启动FlutterActivityFlutter体验之前,短暂地启动标准。为了最大程度地减少这种延迟,您可以FlutterEngine在到达之前预热一个 FlutterActivity,然后可以使用预热的方法FlutterEngine

要预热a FlutterEngine,请在您的应用中找到一个合理的位置以实例化一个FlutterEngine。以下示例FlutterEngineApplication类中任意预热 :

//官方文档是在Application 预热
public class MyApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    // Instantiate a FlutterEngine.
    flutterEngine = new FlutterEngine(this);

    // Start executing Dart code to pre-warm the FlutterEngine.
    flutterEngine.getDartExecutor().executeDartEntrypoint(
      DartEntrypoint.createDefault()
    );

    // Cache the FlutterEngine to be used by FlutterActivity.
    FlutterEngineCache
      .getInstance()
      .put("my_engine", flutterEngine);
  }
}



//以下我学习为了方便写的代码
	FlutterEngine flutterEngine;
  

   @Override
  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化FlutterEngine
        flutterEngine = new FlutterEngine(this);
        flutterEngine.getDartExecutor()
          .executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());

        //添加FlutterEngine
        FlutterEngineCache.getInstance().put("my_engine",flutterEngine);
    
    myButton.addOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
         Intent intent = FlutterActivity
                        .withCachedEngine("my_engine")
                        .build(MainActivity.this);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
      }
    });
   }

3、在Android Activity中加载FlutterView

就如同在Activity中添加Fragment一样的,利用FragmentManner来添加一个Fragment即可

  FlutterEngine flutterEngine;
    private static final String TAG_FLUTTER_FRAGMENT = "flutter_fragment";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        loadFlutterView();
    }

    private void loadFlutterView() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        //这里会报错,不让强转,不理会他
        FlutterFragment  flutterFragment = 		(FlutterFragment)fragmentManager.findFragmentByTag(TAG_FLUTTER_FRAGMENT);
        flutterFragment = FlutterFragment.createDefault();
        fragmentManager.beginTransaction()
                .add(R.id.load_flutter_view,flutterFragment,TAG_FLUTTER_FRAGMENT)
                .commit();
    }

Demo地址: github.com/hdsmathy/Fl…