Recently, the company started to promote the use of Flutter for mobile development. After more than a month of busy Dragon Boat Festival, the company is ready to launch the Flutter hybrid development iteration, writing down the hole of this process and some access processes, as well as the Flutter technology.
Since I am mainly engaged in Android development, iOS is still a rookie, so let me introduce the Android hybrid access process first
1. Create a Flutter Module
In many cases, Flutter access is based on existing mobile projects, which is weaker, less costly, and less risky than hacking into existing projects.
flutter create -t module flutter_module
Copy the code
Input in the command line interface, preferably in the same directory as the original project, the same folder. My project is basically that the original project is a Git repository, and the corresponding Flutter code is in another Git repository, so the version management is better
2. The Android system is connected
Add the code at the end of the existing setting.gradle file
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'/flutter_module/.android/include_flutter.groovy'
))
Copy the code
This will introduce the module resources of the corresponding Flutter. The corresponding compilation script of the Flutter framework has been written. You can read it later if you have time
Add the Flutter dependencies to the build.gradle file in the app directory
implementation project(':flutter')
Copy the code
The main dependency chains are as follows
flutter_module/.android/include_flutter.groovy ->
flutter_module/.android/Flutter/build.gradle ->
$flutterRoot/packages/flutter_tools/gradle/flutter.gradle
Copy the code
The best way to do this is to use the following command line tool in the.Android file under the Flutter project
gradlew assembleDebug
Copy the code
Command to load the Android dependency
3. Native display of Flutter view
Button open = findViewById(R.id.openBtn);
open.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(MainActivity.this, MyFlutterActivity.class); startActivity(intent); }}); public class MyFlutterActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.activity_flutter);
final FlutterView flutterView = Flutter.createView(
this,
getLifecycle(),
"route1"); final FrameLayout layout = findViewById(R.id.flutter_container); layout.addView(flutterView); }}Copy the code
Just need addView in the Activity. It looks simple, but there are many problems. There may be a black screen during the jump process, and the reuse of the Flutter view is also a problem, as well as the corresponding Flutter jump Native interface. As a result, Google found that the FlutterBoost framework solved most of these problems.
4. Access to FlutterBoost framework
In accordance with the github.com/alibaba/flu… The official document, access found a lot of pits, do not know whether developers are disgusted to write the same document.
The access process is as follows:
4.1 The Flutter project is connected to FlutterBoost
Add the dependency to the corresponding pubspec.yaml file, which is a configuration file.
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: '0.0.411'
Copy the code
Then call Package GET, you can see in the upper right corner, and then execute gradlew assembleDebug in the. Android file to complete the dependency download.
4.2 Configuration in the main.dart file of Flutter
@override
void initState() { super.initState(); FlutterBoost. Singleton. RegisterPageBuilders ({/ / the name of the corresponding Page, it is best to class Http format'demoPage': (pageName, params, _) {
returnDemoPage(); }}); FlutterBoost.handleOnStartPage(); } @override Widget build(BuildContext context) {return MaterialApp(
title: 'Flutter Boost example',
builder: FlutterBoost.init(postPush: _onRoutePushed),
home: Container());
}
void _onRoutePushed(
String pageName, String uniqueId, Map params, Route route, Future _) {}
Copy the code
4.3 Setting of Application in Android
@Override
public void onCreate() {
super.onCreate();
initFlutterBoot();
}
private void initFlutterBoot() {
FlutterBoostPlugin.init(new IPlatform() {
@Override
public Application getApplication() {
return mApplication;
}
@Override
public Activity getMainActivity() {// Return null to prevent the MainActivity page from moving upreturn null;
}
@Override
public boolean isDebug() {
returnAppConfig.IS_DEVELOPING; } @override public Boolean startActivity(Context Context, String URL, int requestCode) {// The callback of the Flutter jumpreturn PageRouter.openPageByUrl(context,url,requestCode);
}
@Override
public Map getSettings() {
returnnull; }}); }Copy the code
Pit 1: If getMainActivity returns MainActivity, the layout of the corresponding main page will move up, and null will be fine.
4.4 Jump of Native and Flutter interface
Native–>Fluuter
You can use PageRouter in the official Demo
public class PageRouter {
public static final String COMMISSION_TASK_PAGE = "gamma://flutter/commissionTaskPage";
public static final String NATIVE_CUST_INFO_PAGE_URL = "gamma://native/custInfo";
public static boolean openPageByUrl(Context context, String url) {
return openPageByUrl(context, url, 0, "{}");
}
public static boolean openPageByUrl(Context context, String url, String json) {
return openPageByUrl(context, url, 0, json);
}
public static boolean openPageByUrl(Context context, String url, int requestCode) {
return openPageByUrl(context, url, requestCode, "{}");
}
public static boolean openPageByUrl(Context context, String url, int requestCode, String json) {
try {
if(url. StartsWith (COMMISSION_TASK_PAGE)) {/ / post-loan task Intent Intent = new Intent (context, FlutterPageActivity. Class); intent.putExtra("pageName"."gamma://flutter/commissionTaskPage");
intent.putExtra("json", json);
context.startActivity(intent);
return true;
} else if(url.contains(NATIVE_CUST_INFO_PAGE_URL)) {// Open the client interface Map<String, String> params = getUrlParams(url); AppUIHelper .showCustomerInfoActivity(context, params.get("custId"));
return true;
}
} catch (Throwable t) {
return false; Private static Map getUrlParams(String URL) {Map<String, Object> Map = new HashMap<>(); url = url.replace("?".";");
if(! url.contains(";")) {
return map;
}
if (url.split(";").length > 0) {
String[] arr = url.split(";")[1].split("&");
for (String s : arr) {
String key = s.split("=") [0]; String value = s.split("=") [1]; map.put(key, value); }return map;
} else {
returnmap; }}}Copy the code
In this way, Native pages can be set to start with Native, and Flutter to start with Flutter to make it easier to distinguish.
The corresponding FlutterPageActivity can be modified according to the official Demo.
Pit 2: The following code is best added to the FlutterPageActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
FlutterMain.startInitialization(this);
super.onCreate(savedInstanceState);
}
Copy the code
Otherwise, an error will be reported
Flutter — >Native
This type of jump is similar to activities jumping to each other
FlutterBoost.singleton.openPage(
"${NativeUrl.NATIVE_CUST_INFO}? custId=${custId};"{});Copy the code
A jump of this type is called back to the startActivity method in the flutterBoostplugin. init method of the previous Application, and only received with PageRouter. After doing their own interface jump
5. Packing pits
The following commands need to be executed in the directories of the Flutter to release the package
flutter build apk
Copy the code
This is followed by the normal Android packaging, otherwise the packaged APK jumps to the Flutter page and flashes back