Android Flutter混合開發實現


混合開發

目前來說作為純Flutter開發的app較少,基本都是將flutter作為共用的組件來開發、在Android\iOS原生項目中引入進行使用,而且個人感覺Android Studio對Native引用Flutter項目的支持比較好(AS 3.6)

Android Native中引入Flutter

創建項目

  • 按照一般流程創建即可,此處用的是androidx項目

    創建flutter_module

    1
    2
    //加入--androidx是為了創建androidx的flutter項目,不需要則去掉
    flutter create --androidx -t module flutter_module

一般在Native項目的同級目錄下創建flutter module,方便其他平台項目引用,命名不要使用單一的flutter,在引入flutter module之后,Android Studio會在Native項目下會自動生成一個Fluttermodule

引入flutter_module

  • setting.gradle中添加module依賴

    1
    2
    3
    4
    5
    6
    7
    setBinding(new Binding([gradle: this]))
    evaluate(new File(
    //如果module創建在了Native根目錄下,此處的parentFile需要去掉
    settingsDir.parentFile,
    //創建的flutter module名稱,如果是他人提供的已實現的module,需要先用AS編譯下或運行下`flutter pub get`
    'flutter_module/.android/include_flutter.groovy'
    ))
  • app/build.gradle引用flutter

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    android {
    //....省略
    defaultConfig {
    //...

    //minSdkVersion需要保證大於16
    minSdkVersion 21
    }

    compileOptions {
    //使用java1.8來編譯
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
    }

    }

    dependencies {
    //....省略

    //注意此處引用的是`flutter`,即Native項目自動生成的module
    //而不是import的`flutter module`
    implementation project(':flutter')
    }

使用

Fragment

1
2
3
4
5
6
7
8
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(
android.R.id.content,
//flutter 1.12之后,Flutter類棄用
//Flutter.initialRoute("initialRoute").build()
FlutterFragment.withNewEngine().initialRoute("initialRoute").build()
)
transaction.commit()

Activity

需要先把io.flutter.embedding.android.FlutterActivity添加至AndroidManifest清單中

1
2
3
val intent = io.flutter.embedding.android.FlutterActivity.withNewEngine()
.initialRoute("initialRoute").build(this)
startActivity(intent)

 

View

1.12之后似乎不再建議使用FlutterView來嵌入Native中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

import android.os.Bundle
import android.util.Log
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import io.flutter.embedding.android.FlutterView
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.dart.DartExecutor
import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener

class MainActivity : FlutterActivity() {

lateinit var flutterEngine: FlutterEngine

companion object {
const val TAG = "MainActivity"
}

override fun onCreate(savedInstanceState: Bundle?) {
FlutterMain.startInitialization(applicationContext)
super.onCreate(savedInstanceState)

val layout = FrameLayout(this)
setContentView(layout)
flutterEngine = FlutterEngine(this)
flutterEngine.navigationChannel.setInitialRoute("initialRoute")
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)

val flutterView = FlutterView(this)
val lp = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
)
flutterView.addOnFirstFrameRenderedListener(object : FlutterUiDisplayListener {
override fun onFlutterUiNoLongerDisplayed() {
Log.d(TAG, "onFlutterUiNoLongerDisplayed: ")
}

override fun onFlutterUiDisplayed() {
Log.d(TAG, "onFlutterUiDisplayed: ")
}
})
layout.addView(flutterView, lp)
flutterView.attachToFlutterEngine(flutterEngine)
}

override fun onResume() {
super.onResume()
flutterEngine.lifecycleChannel.appIsResumed()
}

override fun onPause() {
super.onPause()
flutterEngine.lifecycleChannel.appIsPaused()
}

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM