注:说明下,这个连接是中文文档,可是还有不少章节仍是没翻译,例如将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();
复制代码