安卓Native调用Flutter页面

2,257 阅读2分钟

两种方法

  • 方法一:在已有的项目中集成Flutter
  • 方法二:将flutter工程导出为aar包提供给原项目调用(aar和引用工程统一debug或release版本)

参考资料传送门:

www.imuo.com/a/6773770e1… blog.csdn.net/Kinsomy/art…

事前准备

  • 一个可运行的flutter工程,下文统称为 your_flutter。
  1. 提供routes,your_flutter->main.dart
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
      primarySwatch: Colors.blue,
      ),
      // 添加路由
      routes: <String, WidgetBuilder>{
        'PAGE_A': (BuildContext context) => new MyHomePage(title: 'Welcome to PAGE_A'),
        'PAGE_B': (BuildContext context) => new MyHomePage(title: 'Welcome to PAGE_B'),
      },
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
// 需要自己实现 MyHomePage页面内容
  1. 修改your_flutter->AndroidManifest.xml。(注释原来application节点,新建一个简单的)
<!--<application-->
        <!--android:name="io.flutter.app.FlutterApplication"-->
        <!--android:label="your_flutter"-->
        <!--android:icon="@mipmap/ic_launcher">-->
        <!--<activity-->
            <!--android:name=".MainActivity"-->
            <!--android:launchMode="singleTop"-->
            <!--android:theme="@style/LaunchTheme"-->
            <!--android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"-->
            <!--android:hardwareAccelerated="true"-->
            <!--android:windowSoftInputMode="adjustResize">-->
            <!--&lt;!&ndash; This keeps the window background of the activity showing-->
                 <!--until Flutter renders its first frame. It can be removed if-->
                 <!--there is no splash screen (such as the default splash screen-->
                 <!--defined in @style/LaunchTheme). &ndash;&gt;-->
            <!--<meta-data-->
                <!--android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"-->
                <!--android:value="true" />-->
            <!--&lt;!&ndash;<intent-filter>&ndash;&gt;-->
                <!--&lt;!&ndash;<action android:name="android.intent.action.MAIN"/>&ndash;&gt;-->
                <!--&lt;!&ndash;<category android:name="android.intent.category.LAUNCHER"/>&ndash;&gt;-->
            <!--&lt;!&ndash;</intent-filter>&ndash;&gt;-->
        <!--</activity>-->
    <!--</application>-->
    <application>
    <activity
        android:name=".MainActivity"
        android:launchMode="singleTop">
    <meta-data android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
        android:value="true" />
    </activity>
    </application>
  1. 修改your_flutter->MainActivity。(最简版)
public class MainActivity extends FlutterActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    // +添加 startInitialization调用
    io.flutter.view.FlutterMain.startInitialization(this.getApplicationContext());
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
  }
  // +提供一个供myApp工程调用的方法,此方法会跳转到your_flutter下的路由
  public static void start(Context context, String page) {
    Intent intent = new Intent(context, MainActivity.class);
    intent.setAction(Intent.ACTION_RUN);
    intent.putExtra("route", page);
    context.startActivity(intent);
  }

  • 一个原生的安卓工程,下文统称为 myApp

方法一:在已有的项目中集成Flutter

  1. 修改your_flutter->build.gradle。(android.defaultConfig.minSdkVersion 与myApp工程保持一致)
-apply plugin: 'com.android.application'
+apply plugin: 'com.android.library'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
  1. 修改myAPP->setting.gradle 。
-include ':app'
+include ':app', ':your_flutter'
+project(':your_flutter').projectDir = new File(settingsDir, 'your_flutter的路径/android/app')
  1. 修改myAPP->local.properties。
ndk.dir=/Users/andy/Desktop/NDK_ANT/android-ndk-r14b
sdk.dir=/Users/andy/Library/Android/sdk
+flutter.sdk=/Users/andy/flutter/flutter
+flutter.buildMode=dehug
+flutter.versionName=1.0.0
+flutter.versionCode=1
  1. 修改myAPP->build.gradle。
dependencies {
    ...
    +implementation project(":your_flutter")
}
  1. 在myApp工程中提供一个按钮,调用flutter页面。
flutter包名.MainActivity.start(this, "PAGE_A");
  1. 到此完成第一种方法。

方法二:将flutter工程导出为aar包提供给原项目调用

  1. 制作aar,有坑,需要手动处理。(原因参考:blog.csdn.net/Kinsomy/art…

1.1 修改your_flutter->build.gradle,先使用application打出 apk包(android.defaultConfig.minSdkVersion 与myApp工程保持一致)

...
+apply plugin: 'com.android.application'
-apply plugin: 'com.android.library'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
...

1.2 打包apk

方法1:用Android Studio打apk。

方法2:在 your_flutter根目录下shell执行:flutter build apk --debug /flutter build apk --release

  1. 解压 apk,拷贝 /assets/flutter_shared/icudtl.dat文件到your_flutter/app/src/main/assets/flutter_shared目录。(如果用用Android Studio打开的your_flutter,有问题可以重新打开此工程试试)
  2. 修改your_flutter->build.gradle,使用library
...
-apply plugin: 'com.android.application'
+apply plugin: 'com.android.library'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
...
  1. 在 your_flutter根目录下shell执行:flutter build apk --debug /flutter build apk --release,会在 your_flutter/build/app/outputs/aar 文件夹下生成目标aar。
  2. 修改myAPP->setting.gradle 。
+include ':app'
-include ':app', ':your_flutter'
-project(':your_flutter').projectDir = new File(settingsDir, 'your_flutter的路径/android/app')
  1. 修改myAPP->local.properties。
ndk.dir=/Users/andy/Desktop/NDK_ANT/android-ndk-r14b
sdk.dir=/Users/andy/Library/Android/sdk
-flutter.sdk=/Users/andy/flutter/flutter
-flutter.buildMode=dehug
-flutter.versionName=1.0.0
-flutter.versionCode=1
  1. 修改myAPP->build.gradle,使用aar。
dependencies {
    ...
    -implementation project(":your_flutter")
    +compile(name: 'app-release', ext: 'aar')
}
  1. 在myApp工程中提供一个按钮,调用flutter页面。
your_flutter包名.MainActivity.start(this, "PAGE_A");
  1. 到此完成第二种方法。