Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to develop Flutter mixed

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

How to carry out mixed development of Flutter, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain for you in detail, people with this need can come to learn, I hope you can gain something.

Introduction

As a new generation of Google open source cross-platform, high-performance UI framework, Flutter aims to help developers efficiently build exquisite applications that are cross-platform and consistent with UI and interactive experience.

When we need to develop an entirely new application, we can easily start from scratch and develop entirely using Flutter. However, if you need to introduce Flutter technology for an existing application, it is obviously unrealistic to rewrite it all with Flutter. Fortunately, Flutter supports integration into existing applications in the form of separate pages or even UI fragments, the so-called hybrid development model. This paper mainly talks about the mixed development and construction of Flutter under the Android platform from the perspective of Android development.

Hello Flutter

I believe that there should be very few mobile developers who don't know about Flutter, so I won't introduce you too much here. For this technology, the vast majority of those who have used will say yes; if you have not used it, try it and have a Demo experience. It may be the last new technology you need to learn and master. In retrospect, what is the unique charm of Flutter that makes it stand out from all the technologies? To sum up, there are mainly the following points:

Cross-platform: a set of code can be perfectly adapted to Android and iOS platforms, and more platforms will be covered in the future, greatly saving development manpower and maintenance costs, while having excellent cross-end UI performance consistency.

Efficient development: SDK provides rich UI components that can be used out of the box; declarative UI construction greatly reduces the error rate; Debug mode provides hot overloading capability to preview code changes in real time without the need for recompilation and installation.

High performance: self-built rendering engine is used, which is independent of the system and can be optimized separately; different from RN and WEEX, there is no extra overhead for middle-tier conversion; the code in Release mode is compiled to AOT instructions and runs efficiently.

Benefiting from the above core advantages, Flutter has attracted a lot of fans of mobile developers after its launch, and Internet companies have also studied it as a basic technology. In the early days of Flutter, its application scenario was mainly to build a new App from 0, which was not friendly to mixed development. However, as a cross-platform technical framework, we still need to rely on many system capabilities provided by the native platform, in addition, there are many existing native App eager to try, so in the context of this demand, the support and improvement of mixed development has become better and better. Let's start the journey of mixed development and construction of Flutter on Android with a simple example.

Introduction of Flutter module

To use Flutter in an existing Android Project, you need to introduce a Flutter Module. Open the existing Android project in Android Studio (you need to ensure that the Flutter plug-in has been successfully installed and enabled), by using File > New > New Module... Menu, we can create a new Flutter module or import an external Flutter module.

Here, take the simplest Android App project as an example, import the Flutter module. After the Flutter module is successfully imported, some changes will take place in the original project file and structure, mainly including:

The following has been added to the settings.gradle file. In fact, it is to execute the .Android / include_flutter.groovy script file under the corresponding Flutter module, this step will introduce an Android Library Module named Flutter, as well as all the plug-ins that the Flutter module depends on.

SetBinding (new Binding ([gradle: this])) evaluate (new File (settingsDir.parentFile, 'flutter_module/.android/include_flutter.groovy')) include': flutter_module'project (': flutter_module'). ProjectDir = new File ('.. / flutter_module')

The project structure changes, as shown in the following figure:

Before the introduction of the Flutter module, there was only one Module; for app in the project, but after the introduction, you can see that in addition to the original app Module, the Flutter Gradle plug-in automatically introduces several additional sub-Module:

Flutter_module: refers to the target Flutter Module to be introduced, and will not apply Android any plug-ins related to Flutter, mainly including Flutter-related source code, resources, dependencies, and so on.

Flutter: the Android Library Module; introduced for the Flutter Gradle plug-in is mainly responsible for compiling flutter_module and its dependent third-party Package, Dart code for Plugin, and packaging Flutter resources.

Device_info: Flutter Android Plugin Library Module was automatically introduced for the Flutter Gradle plug-in because I initially added a dependency on the plug-in device_info to the pubspec.yaml file of flutter_module. The Flutter Gradle tool introduces the code and resources from the Android platform side of all plug-ins that flutter_module depends on into the project as a Library Module to participate in the construction. If you want to see which Plugin has been introduced into flutter_module, you can look at the. flutter-plugins and .flutter-plugins-dependencies files in their corresponding directory, which are generated when flutter pub get is executed, recording the plug-in's local file directory, dependency information, and so on.

Note: a project cannot contain multiple Flutter Module, and only one can be introduced at most, which is determined by Flutter's Gradle plug-in.

Use Flutter

After the introduction of the Flutter module, let's take a look at how to use Flutter.

Add dependency

First of all, we need to add the dependence on the Flutter project in the build.gradle script file of the App module, only in this way can the Flutter module participate in the construction of the whole application, and we can also call the Java layer API provided by Flutter in the App module. As follows:

Dependencies {implementation project (': flutter')} run the Flutter page

We can choose to use Activity, Fragment, or View to host the UI of Flutter. Here we mainly introduce the first two methods, and assume that a widget has been rendered through the runApp method in flutter_module.

Run Flutter Activity. You can easily start a FlutterActivity using the io.flutter.embedding.android.FlutterActivity class, but we can also inherit it and extend our own logic. The sample code is as follows:

FlutterActivity .withNewEngine () .build (context) .also {startActivity (it)}

Run Flutter Fragment. You can use FlutterFragmentActivity or FlutterFragment to add Flutter UI fragments: a. Using FlutterFragmentActivity, you can automatically create and add a FlutterFragment;b. Manually create the FlutterFragment and add it to the target Activity. The sample code is as follows:

Val flutterFragment = FlutterFragment.withNewEngine () .dartEntrypoint (getDartEntrypointFunctionName ()) .initialRoute (getInitialRoute ()) .appBundlePath (getAppBundlePath ()) .flutterShellArgs (FlutterShellArgs.fromIntent (intent)) .handleDeeplinking (shouldHandleDeeplinking ()) .renderMode (renderMode) .transparencyMode (transparencyMode) .initidAttachEngineToActivity (shouldAttachEngineToActivity ()) .build () fragmentManager .beginTransaction () .add (FRAGMENT_CONTAINER_ID) FlutterFragment, TAG_FLUTTER_FRAGMENT) .commit ()

Platform layer communicates with Flutter layer. Whether developing Plugin or business logic, communication between the platform layer and the Flutter layer is essential, which requires the use of MethodChannel. When the platform layer calls the Flutter layer API through the MethodChannel request, the data is packaged and encoded and transmitted to the Flutter layer through JNI and DartVM for decoding. After the result calculation is completed, the data will be repackaged and encoded and transmitted back to the Native layer through DartVM and JNI. Similarly, when the Flutter layer requests to call the API of the platform layer, the data processing is consistent, but the flow direction is opposite. In this way, a bi-directional and asynchronous communication channel is established between the platform layer and the Flutter layer. In the following sample code, the Native layer uses dev.flutter.example/counter to create a MethodChannel and sets Handler to receive Dart's remote method call incrementCounter and call reportCounter to pass back the result.

Channel = MethodChannel (flutterEngine.dartExecutor, "dev.flutter.example/counter") channel.setMethodCallHandler {call, _-> when (call.method) {"incrementCounter"-> {count++ channel.invokeMethod ("reportCounter", count)}

The Dart layer creates the MethodChannel with the same name, sets the Handler to handle the callback result, and then calls the incrementCounter method to request the counter. The sample code is as follows:

Final _ channel = MethodChannel ('dev.flutter.example/counter'); _ channel.setMethodCallHandler (_ handleMessage); _ channel.invokeMethod (' incrementCounter'); Future _ handleMessage (MethodCall call) async {if (call.method = = 'reportCounter') {_ count = call.arguments as int; notifyListeners ();}}

Here we communicate by manually creating MethodChannel, which is fine in the scenario of simple communication, but it is not very suitable when the communication interface API is more complex.

First, it is tedious, because we need to write a lot of handwritten packing and unpacking code; second, it is easy to make mistakes. At this point, it's Pigeon's turn to show his skills. Pigeon is an official code generation tool that can generate type-safe two-way communication API interfaces. For details, please refer to the official Example, which will not be discussed here.

Pigeon: https://flutter.dev/docs/development/platform-integration/platform-channels#pigeon

Flutter APK parsing

Now that we know how to introduce and use Flutter in an existing Android project, let's explore the structure of Flutter APK to see what Flutter Tools packages in this APK package. The following two figures show the Flutter APK package structure built in Debub mode and Release mode respectively, ignoring non-Flutter related items.

You can see that the structure of the APK in the two modes is roughly the same, as shown below:

Lib/ {arch} / libflutter.so: the Flutter Engine shared library of the corresponding architecture, which is responsible for Flutter rendering, JNI communication and DartVM. If you do not need the version of the corresponding architecture, you can Exclude it through abiFilters.

Lib/ {arch} / libapp.so: exists only in Release mode, and the shared library contains binary instructions and data generated by Dart AOT. At run time, Flutter Engine reads the corresponding executable machine instructions and data from the shared library through Dynamic Load.

Related resources referenced by assets/flutter_assets:Flutter

Fonts: contains the font library.

FontManifest.json: the font library manifest file referenced, json format, all fonts used, and the path of the font file under flutter_assets.

AssetManifest.json: other resource manifest file, json format, for the mapping of all resource names to resource paths. When Flutter loads a resource, it will find the resource in the corresponding path through this configuration list, read it and load it.

Kernel_blob.bin, isolate_snapshot_data, vm_snapshot_data: only exist in Debug mode, which are DartVM bytecode and data, respectively, and their functions are similar to libapp.so, except that the existing forms and packaging methods are different. In Debug mode, Flutter Tools packages instructions and data separately, mainly for HotReload services, while in Release mode, it is uniformly packaged into shared libraries.

Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report