前言:
各位同學的大家好,有段時間沒有給大家更新文章了,最近在學習flutter和安卓混合開發的知識點。所以就像總結一下,然后后分享給大家。 這一期文章的講的知識一定要有用到Android studio 所以用vscode開發同學要稍微改下IDE (但是這不是重點)
那么廢話不多說我們正式開始。
准備工作
需要安裝flutter的開發環境:大家可以去看看之前的教程:
1 win系統flutter開發環境安裝教程: https://www.jianshu.com/p/152447bc8718
2 mac系統flutter開發環境安裝教程:https://www.jianshu.com/p/bad2c35b41e3
效果圖:


具體實現
一 創建flutter_module 工程
-
1用Android studio 創建或者命令都可以


-
2 命令創建
flutter create -t module flutter_module
這里要注意安卓原生項目需要跟flutter_module在同一個目錄層級
第二步創建安卓原生工程


這個就比較簡單了 我就不多說了按照截圖一路下一步即可
三在Android 項目中進入flutter_module
-
1 在原生Android項目里面的 app目錄下面的 build.gradle里面添加如下代碼
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

我們知道這是使用Java 8所需要的配置,在這里的作用是為了解決版本兼容問題,如果不配置的話運行項目可能會報錯:Invoke-customs are only supported starting with Android O (--min-api 26)。
-
2然后在項目根目錄下的setting.gradle文件中配置:
// 加入下面配置
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'flutter_module/.android/include_flutter.groovy'
))

flutter_module 這個記得修改成自己的flutter module 的名稱 之后sync 一下·項目 即可導入成功
坑
這里要注意我們在sync 的時候我們要同時打開flutter module 項目和原生安卓項目否則會失敗

sync之后我們發現原生工程工程的目錄結構里面多出一flutter名字的library module 的庫工程 我們需要在app目錄下的build.gradle 里面添加該module的依賴
implementation project(':flutter')

這樣我們就講flutter_module工程引入到我們的Android項目項目里面來 當然flutter_module其實也是可以單獨運行的
android 原生頁面打開flutter頁面
-
一添加普通的Flutter屏幕
Flutter提供FlutterActivity了在Android應用程序中顯示Flutter體驗的功能。像任何其他一樣Activity, FlutterActivity必須在您的帳戶中注冊 AndroidManifest.xml。將以下XML添加到 標簽AndroidManifestxml下的文件中application:
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:theme="@style/Theme.Nativedemo"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
/>
-
二 啟動activity
- 1使用FlutterActivity.createDefaultIntent
startActivity(FlutterActivity.createDefaultIntent(MainActivity.this));
這個示例假設您的Dart入口點稱為main(),初始Flutter路線為“ /”。無法使用更改Dart入口點Intent,但可以使用更改初始路線Intent。這個方法打開的是flutter默認入口不能自定義你想要打開的flutter的頁面
- 2 使用 FlutterActivity.withNewEngine().initialRoute 這種方式
startActivity(FlutterActivity.withNewEngine().initialRoute("route_page").build(MainActivity.this));
這個就可以通過在 initialRoute 里面傳入你flutter module 項目里面配置的命名路由地址 從而選擇打開你想要打開的flutter頁面
- 3 啟動flutteractivity並且傳值


我們還是在通過 FlutterActivity.withNewEngine().initialRoute 在initialRoute 里面傳傳值
startActivity(FlutterActivity.withNewEngine().initialRoute("{name:'xq9527'}").build(MainActivity.this));
flutter module 里面如何接收數據
import 'package:flutter/material.dart';
import 'dart:ui';
import 'my_home_page.dart';
import 'default_page.dart';
void main() => runApp(
MyApp(initParams:window.defaultRouteName));
class MyApp extends StatelessWidget {
String initParams = '';
MyApp({this.initParams});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// routes: {
// "/": (context) => DefaultPage(title: '路由默認頁面'),
// 'route_page':(context) => MyHomePage(title: '路由頁面Page1'),
// },
// home: "/",
home: MyHomePage(title: this.initParams,),
);
}
}
在flutter module 我們需要在入口main方法中實例化的myapp 入口的時候 傳入window.defaultRouteName 我們的默認路由的參數 然后在我們的flutter中去使用原生傳過來的數據
使用FlutterEngine
package com.example.nativedemo;
import android.app.Application;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;
/***
*
*創建人xuqing
* 創建時間:2021/4/20
* 類說明:啟動入口
*/
public class MyApplication extends Application {
public static final String ENGINEID = "my_engine_id";
@Override
public void onCreate() {
super.onCreate();
initFlutterEngine();
}
private void initFlutterEngine(){
// Instantiate a FlutterEngine.
FlutterEngine flutterEngine = new FlutterEngine(this);
flutterEngine.getNavigationChannel().setInitialRoute("route_page");// 配置默認啟動路由
// Start executing Dart code to pre-warm the FlutterEngine.
flutterEngine.getDartExecutor().executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
);
// Cache the FlutterEngine to be used by FlutterActivity.
FlutterEngineCache
.getInstance()
.put(ENGINEID, flutterEngine);
}
}
使用方式
FlutterActivity.withCachedEngine(MyApplication.ENGINEI).build(MainActivity.this);
使用FlutterFragment
-
默認啟動方式
FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
FlutterFragment flutterFragment=null;
//默認啟動方式
flutterFragment = FlutterFragment.createDefault();
fragmentTransaction.add(R.id.main_framelayout, flutterFragment);
fragmentTransaction.commit();
-
指定路由頁面
FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
FlutterFragment flutterFragment== FlutterFragment.withNewEngine()
.initialRoute("route_page")
.build();
fragmentTransaction.add(R.id.main_framelayout, flutterFragment);
fragmentTransaction.commit();
-
使用FlutterEngine
FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
FlutterFragment flutterFragment== FlutterFragment.withCachedEngine(MyApplication.ENGINEID)
.renderMode(RenderMode.surface)
.build();
fragmentTransaction.add(R.id.main_framelayout, flutterFragment);
fragmentTransaction.commit();
還有可以使用flutterview 我這邊就不展開講了有興趣的同學可以查看官方文檔
Add Flutter to existing apps
最后總結
Android 原生引入flutter module 實現起來相對比較簡單 官方文檔也比較詳細,但是也有坑,我在文章中也提到了 這一期文章主要介紹了Android 引入flutter module 的基礎知識點 如果有紕漏請指正謝謝。最后希望我的文章能幫助到各位解決問題 ,以后我還會貢獻更多有用的代碼分享給大家。各位同學如果覺得文章還不錯 ,麻煩給關注和star,小弟在這里謝過啦
