现有Android项目集成Flutter Module
- 在现有Android项目同级目录终端创建flutter module
flutter create -t module --org com.tikeyc flutter_module -i objc -a java
- 注意事项
settings.gradle文件
rootProject.name = "FlutterAndroid"
include ':app'
// 增加下面代码,Android项目和flutter_module项目在同级目录时
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'flutter_module/.android/include_flutter.groovy'
))
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
改为
/*
FAIL_ON_PROJECT_REPOS
表示如果工程单独设置了仓库,或工程的插件设置了仓库,构建就直接报错抛出异常
PREFER_PROJECT
表示如果工程单独设置了仓库,就优先使用工程配置的,忽略settings里面的
PREFER_SETTINGS
表述任何通过工程单独设置或插件设置的仓库,都会被忽略
*/
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
否则报错:
Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed to apply plugin class 'FlutterPlugin'.
但是这样改了以后,那么原来setting.gradle下面设置的全局配置的镜像就没用了
解决方式:在主工程目录下的gradle添加镜像
allprojects{
repositories {
maven { url "https://jitpack.io" }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}
google()
mavenCentral()
}
}
- 主项目添加flutter模块
app的build.gradle
文件
implementation project(path: ':flutter')
- 示例代码
MyApplication
public class MyApplication extends Application {
public static final String MY_ENGINE_ID = "my_engine_id";
public FlutterEngine flutterEngine;
@Override
public void onCreate() {
super.onCreate();
initFlutterEngine();
}
private void initFlutterEngine() {
// Instantiate a FlutterEngine.
flutterEngine = new FlutterEngine(this);
// Configure an initial route.
flutterEngine.getNavigationChannel().setInitialRoute("/");
// 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(MY_ENGINE_ID, flutterEngine);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".MyApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.FlutterAndroid"
tools:targetApi="31">
<activity
android:name=".MyFragmentActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:theme="@style/Theme.FlutterAndroid"
android:windowSoftInputMode="adjustResize" />
</application>
</manifest>
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 默认启动方式
LinearLayout linearLayout = findViewById(R.id.my_button_super);
Button button1 = linearLayout.findViewById(R.id.my_button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = FlutterActivity.createDefaultIntent(MainActivity.this);
startActivity(intent);
}
});
// initialRoute初始化路由
Button button2 = linearLayout.findViewById(R.id.my_button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = FlutterActivity
.withNewEngine()
.initialRoute("/")
.build(MainActivity.this);
startActivity(intent);
}
});
// 使用缓存的FlutterEngine,明显提高启动性能
Button button3 = linearLayout.findViewById(R.id.my_button3);
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = FlutterActivity
.withCachedEngine(MyApplication.MY_ENGINE_ID)
.build(MainActivity.this);
startActivity(intent);
}
});
// 打开FlutterFragment
Button button4 = linearLayout.findViewById(R.id.my_button4);
button4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, MyFragmentActivity.class);
startActivity(intent);
}
});
//
FlutterView flutterView = new FlutterView(this);
}
}
MyFragmentActivity
public class MyFragmentActivity extends FragmentActivity {
// Define a tag String to represent the FlutterFragment within this
// Activity's FragmentManager. This value can be whatever you'd like.
private static final String TAG_FLUTTER_FRAGMENT = "flutter_fragment";
// Declare a local variable to reference the FlutterFragment so that you
// can forward calls to it later.
private FlutterFragment flutterFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Inflate a layout that has a container for your FlutterFragment.
// For this example, assume that a FrameLayout exists with an ID of
// R.id.fragment_container.
setContentView(R.layout.activity_my_fragment);
// Get a reference to the Activity's FragmentManager to add a new
// FlutterFragment, or find an existing one.
FragmentManager fragmentManager = getSupportFragmentManager();
// Attempt to find an existing FlutterFragment,
// in case this is not the first time that onCreate() was run.
flutterFragment = (FlutterFragment) fragmentManager
.findFragmentByTag(TAG_FLUTTER_FRAGMENT);
// Create and attach a FlutterFragment if one does not exist.
if (flutterFragment == null) {
// flutterFragment = FlutterFragment.createDefault();
// flutterFragment = FlutterFragment
// .withNewEngine()
//// .dartEntrypoint()
// .initialRoute("/")
// .build();
flutterFragment = FlutterFragment
.withCachedEngine(MyApplication.MY_ENGINE_ID)
// .shouldAttachEngineToActivity(false) // 以免 Flutter 控制 Activity 的系统 UI,可以使用 FlutterFragment 的 Builder 中的 shouldAttachEngineToActivity() 方法
.build();
fragmentManager
.beginTransaction()
.add(R.id.fragment_container, flutterFragment, TAG_FLUTTER_FRAGMENT)
.commit();
}
}
@Override
public void onPostResume() {
super.onPostResume();
flutterFragment.onPostResume();
}
@Override
protected void onNewIntent(@NonNull Intent intent) {
super.onNewIntent(intent);
flutterFragment.onNewIntent(intent);
}
@Override
public void onBackPressed() {
flutterFragment.onBackPressed();
}
@Override
public void onRequestPermissionsResult(
int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
flutterFragment.onRequestPermissionsResult(
requestCode,
permissions,
grantResults
);
}
@Override
public void onUserLeaveHint() {
flutterFragment.onUserLeaveHint();
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
flutterFragment.onTrimMemory(level);
}
}