注:說明下,這個連接是中文文檔,可是還有不少章節仍是沒翻譯,例如將Flutter module集成到Android項目的章節。ios的已被翻譯,大佬們都是喜歡玩ios,因此首先翻譯ios?java
android {
//...
defaultConfig {
ndk {
// 限制下架構,Flutter僅支持:armeabi-v7a 和 arm64-v8a 架構(目前1.12版本)
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}
複製代碼
android {
//...
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
複製代碼
注:Android Studio支持自動導入,前提條件是:Android項目和Flutter Module在同一文件夾下。android
注:只須要設置下就好了,上面自動導入,就是默認生成代碼的。ios
dependencies {
implementation project(':flutter')
}
複製代碼
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'flutter_module/.android/include_flutter.groovy'
))
複製代碼
通常默認生成的是下述代碼形式include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir,
'../flutter_module/.android/include_flutter.groovy'
))
複製代碼
使用FlutterActivity的形式,呈現Flutter界面十分方便緩存
前置條件:FlutterActivity 必須在 AndroidManifest.xml 中註冊bash
<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"
/>
複製代碼
啓動Flutter Module默認路由(最簡單形式)架構
Intent intent = FlutterActivity.createDefaultIntent(this);
startActivity(intent);
複製代碼
這樣能夠直接跳轉到Flutter界面,實際是啓動FlutterActivity,在FlutterActivity裏面加載Flutter的Ui界面。app
選擇性跳轉某個路由界面ide
Intent intent = FlutterActivity.withNewEngine()
.initialRoute("/you/route/") //設置你的路由地址
.build(this);
startActivity(intent);
複製代碼
實際上createDefaultIntent()方法裏面就是封裝了withNewEngine().build(launchContext)方法,有興趣的,能夠點進代碼裏面看看。佈局
使用緩存的 FlutterEnginegradle
//使用緩存的FlutterEngine(最大程度地減小啓動標準的延遲)
FlutterEngine flutterEngine = new FlutterEngine(this); //初始路由
//flutterEngine.getNavigationChannel().setInitialRoute("your/route/here"); //自定義路由
//開始執行Dart代碼以預熱FlutterEngine。
flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());
//緩存FlutterActivity要使用的FlutterEngine。
FlutterEngineCache.getInstance().put("my_engine_id", flutterEngine);
Intent intent = FlutterActivity
.withCachedEngine("my_engine_id")
.build(this);
//某個按鈕的點擊事件
findViewById(R.id.flutter_button).setOnClickListener(v -> {
startActivity(intent);
});
複製代碼
說明下:實際上FlutterActivity.withNewEngine()...方式跳轉,都是新生成一個FlutterEngine對象,每一個FlutterEngine都有一個很是重要的預熱時間。這意味着啓動一個標準的FlutterActivity 會在Flutter體驗變得可見以前有一個短暫的延遲。爲了最小化這個延遲,咱們能夠在到達FlutterActivity以前預熱FlutterEngine,而後可使用緩存的FlutterEngine。這種狀況在debug安裝的狀況尤爲顯著,會有一段時間黑屏,提早緩存好FlutterEngine,能夠避免這種狀況,提高交互體驗,推薦。
說明:FlutterFragment可用的地方仍是蠻多的,可用於顯示一個滑動的抽屜、標籤式內容、 ViewPager 中的一個頁面等等,固然,若是FlutterActivity能解決,建議使用FlutterActivity,由於FlutterActivity更容易使用。 官網原話:If an Activity is equally applicable for your application needs, consider using a FlutterActivity instead of a FlutterFragment, which is quicker and easier to use.
使用FlutterFragment
public class MyActivity extends FragmentActivity {
private FlutterFragment flutterFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity_layout);
//直接啓動FlutterFragment
FragmentManager fragmentManager = getSupportFragmentManager();
//默認路由,至關於:initialRoute("/")
//FlutterFragment flutterFragment = FlutterFragment.createDefault();
FlutterFragment flutterFragment = FlutterFragment.withNewEngine()
.initialRoute("/") //設置路由
.build();
fragmentManager
.beginTransaction()
.add(R.id.flutter_ui, flutterFragment, "flutter_fragment")
.commit();
}
}
複製代碼
R.id.flutter_ui:是佈局文件裏面一個Fragment的id
比較坑比的地方
FlutterFragment沒法強轉成Fragment類型,涉及到強轉的部分會爆紅,可是不影響運行。
緣由:看了下FlutterFragment,繼承Fragment的,子類強轉父類是沒問題的,可是很坑的是,FlutterFragment裏面用的是Support包,我用的是Androidx,致使倆個對象無法強轉。 就是:support.v4.app.Fragment的子類無法強轉成androidx.fragment.app.Fragment ? 這個報錯真是血坑。
解決辦法:在下只找到了可能的緣由,實在找不到解決之法。可能的解決辦法
使用上面的代碼,足以把你的Flutter頁面展現出來了
使FlutterFragment週期和Activity同步
public class MyActivity extends FragmentActivity {
@Override
public void onPostResume() {
super.onPostResume();
flutterFragment.onPostResume();
}
@Override
protected void onNewIntent(@NonNull Intent intent) {
flutterFragment.onNewIntent(intent);
}
@Override
public void onBackPressed() {
flutterFragment.onBackPressed();
}
@Override
public void onRequestPermissionsResult(
int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults
) {
flutterFragment.onRequestPermissionsResult(
requestCode,
permissions,
grantResults
);
}
@Override
public void onUserLeaveHint() {
flutterFragment.onUserLeaveHint();
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
flutterFragment.onTrimMemory(level);
}
}
複製代碼
使用緩存的 FlutterEngine
//使用緩存的FlutterEngine(最大程度地減小啓動標準的延遲)
FragmentManager fragmentManager = getSupportFragmentManager();
FlutterEngine flutterEngine = new FlutterEngine(this); //初始路由
// flutterEngine.getNavigationChannel().setInitialRoute("/"); //自定義路由
//開始執行Dart代碼以預熱FlutterEngine。
flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());
FlutterEngineCache.getInstance().put("my_engine_id", flutterEngine);//緩存要使用的FlutterEngine。
//點擊事件
findViewById(R.id.flutter_button).setOnClickListener(v -> {
FlutterFragment flutterFragment = FlutterFragment.withCachedEngine("my_engine_id").build();
fragmentManager
.beginTransaction()
.add(R.id.flutter_ui, flutterFragment, "flutter_fragment")
.commit();
});
複製代碼
基本上和上面使用FlutterActivity緩存機制同樣
flutterFragment.withCachedEngine("my_engine_id").build();
複製代碼
真是嗶嗶了狗,我還覺得withCachedEngine("my_engine_id").build()直接把緩存的FlutterEngine寫入到flutterFragment對象裏面,實際上,build() 返回的是FlutterFragment對象,上面的代碼只是取設置好的FlutterFragment。
fragmentManager
.beginTransaction()
.add(R.id.flutter_ui, flutterFragment.withCachedEngine("my_engine_id").build(), "flutter_fragment")
.commit();
複製代碼