Flutter 混合開發系列 包含以下:java
- 嵌入原生View-Android
- 嵌入原生View-iOS
- 與原生通訊-MethodChannel
- 與原生通訊-BasicMessageChannel
- 與原生通訊-EventChannel
- 添加 Flutter 到 Android Activity
- 添加 Flutter 到 Android Fragment
- 添加 Flutter 到 iOS
每一個工做日分享一篇,歡迎關注、點贊及轉發。android
Flutter能夠以源代碼或AAR的方法嵌入到Android原生項目,集成流程可使用 Android Studio 完成,也能夠手動完成。強烈建議使用 Android Studio。git
首先建立一個 Android 項目,建立一個空的 Activity:緩存
Android 項目建立成功後,使用Android Studio 添加Flutter模塊,在Android原生項目中點擊「File > New > New Module...」,建立 Flutter Module:微信
注意:Android Studio 的版本3.5及以上,Flutter IntelliJ plugin版本42及以上。app
在彈出的選擇Module類型的對話框中選中Flutter Module,而後點擊Next,less
設置Flutter module的Project name、Flutter SDK等,點擊Next:ide
設置Flutter module的包名,點擊Finish:性能
編譯完成後將在當前App目錄下生成Flutter模塊的代碼,目錄結構以下:測試
將 Flutter 頁面加載到 MainActivity(默認啓動頁) 中,修改 MainActivity :
package com.flutter.androidflutter import io.flutter.embedding.android.FlutterActivity class MainActivity : FlutterActivity()
你沒有看錯,只需讓 MainActivity 繼承 FlutterActivity 便可。
注意:FlutterActivity的包名是io.flutter.embedding.android.FlutterActivity
MainActivity(默認啓動頁)添加一個按鈕,點擊後跳轉到新的頁面,此頁面加載 Flutter ,MainActivity代碼以下:
package com.flutter.androidflutter import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import io.flutter.embedding.android.FlutterActivity import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) button.setOnClickListener { startActivity(Intent(this,SecondFlutterActivity::class.java)) } } }
SecondFlutterActivity 代碼以下:
package com.flutter.androidflutter import io.flutter.embedding.android.FlutterActivity class SecondFlutterActivity:FlutterActivity()
在 AndroidManifest.xml 中註冊此 Activity:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.flutter.androidflutter"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> ... <activity android:name=".SecondFlutterActivity"/> </application> </manifest>
SecondFlutterActivity 只是繼承了 FlutterActivity,這種狀況下,也能夠直接使用 FlutterActivity:
startActivity(Intent(this, FlutterActivity::class.java))
或者:
startActivity(FlutterActivity.createDefaultIntent(this))
在 AndroidManifest.xml 中註冊 FlutterActivity:
<activity android:name="io.flutter.embedding.android.FlutterActivity"/>
效果與上面是同樣的。
FlutterActivity 會加載 Flutter Module 中 lib/main.dart 中 main 方法,若是有多個Flutter頁面,如何指定跳轉,好比如今有 OnePage Flutter 頁面,OnePage 代碼以下:
class OnePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: Center( child: Text('這是 One 頁面'), ), ); } }
FlutterActivity 指定加載頁面須要使用命名路由,MyApp 修改以下:
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), routes: { 'one_page':(context){ return OnePage(); }, 'two_page':(context){ return TwoPage(); } }, home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
MainActivity 頁面點擊到 Flutter 頁面,加載 OnePage 頁面:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) button.setOnClickListener { startActivity( FlutterActivity .withNewEngine() .initialRoute("one_page") .build(this) ) } } }
加載 FlutterActivity 頁面時明顯看到一段時間的黑屏,這段時間主要是啓動 Flutter 引擎(FlutterEngine),Flutter 引擎啓動的時間在不一樣手機上不一樣,性能越好的手機越短。同時每個 FlutterActivity 頁面都會啓動一個引擎,因此強烈建議不要在一個項目中建立多個 FlutterActivity(或者啓動多個 FlutterActivity 實例),不然內存會愈來愈大,下面是每隔3秒建立一個 FlutterActivity 實例內存變化圖:
爲了減小 FlutterActivity 頁面的延遲時間和多個 FlutterActivity 實例內存一直增加問題,咱們可使用 Flutter 引擎(FlutterEngine)緩存,在啓動 FlutterActivity 前先啓動 Flutter 引擎,而後使用緩存的引擎加載頁面,一般將其放在 Application 中:
class MyApplication : Application() { lateinit var flutterEngine: FlutterEngine override fun onCreate() { super.onCreate() flutterEngine = FlutterEngine(this) flutterEngine.dartExecutor.executeDartEntrypoint( DartExecutor.DartEntrypoint.createDefault() ) FlutterEngineCache .getInstance() .put("engine_id", flutterEngine) } }
使用緩存的引擎:
startActivity( FlutterActivity .withCachedEngine("engine_id") .build(this) )
在同一臺手機上效果很是明顯,黑屏時間大大減小,不過仍是有一個短暫的黑屏。
這裏要注意,使用緩存引擎時,其生命週期不在是 FlutterActivity(或者 FlutterFragment)的生命週期,而是整個 App 的生命週期(在Application 中的建立和銷燬)。固然也能夠提早銷燬:
flutterEngine.destroy()
另外項目的 debug 和 release 版本對性能的影響很是大,若是要測試其性能必定在要 release 下測試。
上面使用新的引擎能夠指定 FlutterActivity(或者 FlutterFragment)配置初始路由,但使用緩存引擎時沒法在 FlutterActivity(或者 FlutterFragment)配置初始路由,由於緩存引擎已經啓動並運行,不過能夠在啓動緩存引擎時指定其初始路由:
flutterEngine = FlutterEngine(this) flutterEngine.navigationChannel.setInitialRoute("one_page") flutterEngine.dartExecutor.executeDartEntrypoint( DartExecutor.DartEntrypoint.createDefault() ) FlutterEngineCache .getInstance() .put("engine_id", flutterEngine)
若是使用緩存引擎在FlutterActivity(或 FlutterFragment)指定不一樣路由,如何處理?這時須要建立一個 method channel,flutter 接收具體消息從而切換不一樣的路由。
老孟Flutter博客(330個控件用法+實戰入門系列文章):http://laomengit.com
歡迎加入Flutter交流羣(微信:laomengit)、關注公衆號【老孟Flutter】:
![]() |
![]() |