Repository navigation
Import multiple Flutter modules in a native app #39707
Description
Hello guys,
I'm Matheus Romão, software engineer at ArcTouch. Here, we are going with Flutter as the technology choice for an important project but recently hit a major roadblock. The principal difficulty relates to using different Flutter modules on different projects. Further explanation and proposal can be found on this issue.
TL;DR: We would like to import different modules in the same project, so we could reuse them in different projects. Today if we try that, we won't pass from Project Sync on Android or pod install on iOS.
Use case
Following the add-to-app guide we can import a Flutter module to an existing native app. However, there's no way to import multiple modules and access each module unitarily.
For example, if we have the following structure:
- flutter-modules
- login
- register
- (...) other modules/features
- android-project
- ios-project
- (...) other projects
It would be nice if there were a way to import login and register modules depending on the needs of each project, so we could reuse them.
Android
Following the "depend on the module's source code" method, I was able to "import" both modules (login and register, in the example) leaving one of the include_flutter.groovy script as it is and changing the other, renaming :flutter to :register. I'm no specialist in gradle/groovy, but I'm pretty sure that was a workaround to make the script work in project sync phase because if you change :flutter to another name in both scripts, the project sync won't work, it will raise an exception:
> Failed to notify project evaluation listener.
> assert flutterProject != null
| |
null false
[...]
Anyway, the project sync works if you leave one script as it is and change the other. However, if you try to run the app, even without using Flutter inside of it, the build fails with the following exception:
Task :app:mergeDebugNativeLibs FAILED
More than one file was found with OS independent path 'lib/x86/libflutter.so'
Which makes sense for me as I'm trying to import Flutter twice.
If I try to import the modules following the "Depend on the Android Archive (AAR)" method, the project sync works. But when you try to run the app the build fails with the following message:
Execution failed for task ':app:checkDebugDuplicateClasses'.
> 1 exception was raised by workers:
java.lang.RuntimeException: Duplicate class io.flutter.BuildConfig found in modules flutter.jar (com.arctouch.login:flutter_debug:1.0) and flutter.jar (com.arctouch.register:flutter_debug:1.0)
[...]
Same problem with duplicates.
iOS
I wasn't able to import the modules using a Podfile. First, install_all_flutter_pods accepts only one module and if we try to call that twice in the same target, we get an error:
Invalid `Podfile` file: Script phase with name `Run Flutter Build Script` name already present for target `iOS Native`.
But I went to podhelper.rb to check the reference and found install_flutter_application_pod, so I tried to run the following Podfile:
login = '../flutter_modules/login'
register = '../flutter_modules/register'
load File.join(login, '.ios', 'Flutter', 'podhelper.rb')
load File.join(register, '.ios', 'Flutter', 'podhelper.rb')
target 'iOS Native' do
install_flutter_engine_pod
install_flutter_application_pod(login)
install_flutter_application_pod(register)
end
But I still got the same error "script phase already present for target".
Workaround
At last, discussing all of that with my colleagues, they suggested trying to import all the modules in an umbrella-like project and then import in the native app. So, I tried to import both modules as packages of a third module, here called umbrella:
umbrella/pubspec.yaml:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
login:
path: ../flutter_modules/login
register:
path: ../flutter_modules/register
That works, but you have to create the routes in the umbrella module to map the login and register widgets.
Well, clearly this is not desirable and it feels pretty hacky. In addition, it adds one more layer to the import process and depending on the method you use, you'll have to repeat some steps as the need for modules change.
Proposal
We should be able to import each module and access its features individually.
For Android, it would be great if we could import Flutter engine and then the modules:
implementation project(:flutter)
implementation project(:login)
implementation project(:register)
After that, we could specify which module and route we want to use in the Flutter view/fragment/activity (facade or Android embedding). Also, the same idea applies to ".aar" method.
For iOS, we could do something like the Podfile above, calling install_flutter_application_pod for each module we want to import or even use varags to pass an array of modules on install_all_flutter_pods.
Thank you guys for taking your time to read this (sorry for the long issue)!
Activity
jmagman commentedon Sep 9, 2019
@xster
xster commentedon Sep 10, 2019
Thanks for describing in detail. This concept is on our mind but likely not something we'll support in an MVP this year. The main work here is to split our deliverables from being 2 pieces (libflutter.so + libapp.so or Flutter.framework + App.framework) into 3 pieces:
1- the Flutter C++ engine with small bits in Java/Objective-C (1)
2- the Flutter Dart framework AOTs (1)
3- your Flutter module AOT (n)
and a bunch of tooling dealing with mismatches.
In the meantime, you'll likely need to create a glue project to bring in all your Flutter modules together in CI or manually before importing like you suggested.
xster commentedon Sep 12, 2019
Copying in from #40343
From @Vanethos:
Objective
Create a native library for iOS and Android that has Flutter bundled in so that native developers can use this library without the need of installing flutter
Steps taken
This gives the following outcome:
The instruction followed were the ones in the following link: adding flutter aar file to an android app
What is noticed is that if the same steps are used to add flutter to an android host, as is detailed in the guide, then the code can compile and it all works out in an emulator.
I've also created a repository with a minimal example to reproduce the issue: https://github.com/Vanethos/modulated-add-to-app
As requested, I'll tag @blasten in this issue
Vanethos commentedon Sep 13, 2019
@xster thank you for merging the issue
As I understand you said that this will not have any new updates during this year?
xster commentedon Sep 17, 2019
Right. Unless we see signs of this being a more common pattern, there are more pressing issues we're currently focused on this year.
Vanethos commentedon Sep 18, 2019
Well, unfortunately, that means that I'll have to port my codebase to native :(
jmagman commentedon Sep 18, 2019
Can you accomplish the same thing by creating and re-using Flutter plugins, and importing them into your existing app with a single module?
Vanethos commentedon Sep 19, 2019
@jmagman the problem is that we are doing this to create a native library to be used in Android and iOS.
Our clients don't have flutter installed in their machines and some of them will not be able to. So we need to be able to compile a sort of .aar and pod that has native code, flutter code and the flutter engine
Since we need this to work before the end of the year, unfortunately, I'm already porting our codebase to swift and kotlin (3 code bases to manage,yay!...)
jmagman commentedon Sep 19, 2019
@Vanethos The aar work is done, instructions here: https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps#1-depend-on-the-android-archive-aar
The iOS framework work is being tracked here: #36968
@arctouch-matheusromao Could you implement the
loginandregistermodules instead with two different plugins? Then you would only need one module per app, and the plugins could be reused between them?It looks like this issue may need to have the errors you documented split out into several trackable issues.
arctouch-matheusromao commentedon Sep 19, 2019
Hey @jmagman,
Those modules were here just for the sake of the explanation. Our work environment revolves around various products, some new and other already existent. We would like to be able to share different modules across different projects. Some of those modules could be plugins, but unfortunately, others can't, as they would have UI flows. Actually, we do have a use-case that we could implement plugins and consume that inside one module. But, that's just one module.
Just to be more clear, let's say we have a restaurant and we already have an Android app for our waiters to handle the orders. But our business is growing and we are already midway through the iOS native app development for our users to pay. Finally, we do have plans to build another app to handle all the back-office operations.
So, for our restaurant we have three projects:
At this point, we already have designs for our brand and we want to preserve that across the apps. So, there are a lot of features that could be shared between those projects. For example, we have
loginandregisterthat could be reused on the user app (both Android and iOS), but for the manager app we don't need theregistermodule, as we already have the registered users and we don't want any external users accessing this app. Another example would be a news feed. If we ever want to share any news on our platform, that could be made in a module and reused in all apps.I hope this example helps to clarify why some business may choose to use Flutter. This would be an incredible opportunity to get work done faster than in any other framework and help a lot of businesses.
Vanethos commentedon Sep 20, 2019
@jmagman but, as I have discussed in my issue, my problem is not adding the aar to an app but it is a problem adding an aar to a module.
Unfortunately the native implementation has already started.. :'(
arctouch-matheusromao commentedon Sep 23, 2019
@xster and @matthew-carroll, do you guys know if it's possible to send messages through a Platform Channel between a Flutter module and a Flutter app?
In our context here (explained in this issue), I'm exposing the umbrella module to an iOS app, which consumes all the events from our modules using a channel. That is working nicely. Now we need to import those modules inside a Flutter app. I fell like I don't need to import the umbrella and just import directly the modules that I need.
In the example above, say I want to import the login module inside my Flutter app, but the login module already has an implemented channel, which sends user events. How can I listen to that inside the Flutter app?
I thought I could just do that in the Flutter app:
Where
channelNameis the same for the login module.However, it doesn't work. Here's the output:
Is there a way that I can use the same
binaryMessengerfor the app and the module? Or it doesn't matter? Do we have aregistraror something similar to a plugin inside the application? So I can pass thebinaryMessengerto the channel creation.I know I can just pass a handler method to the module, but that would also mean changes in the implementation inside the module. Right now we are trying to avoid this path.
Thanks!
29 remaining items
nailgilaziev commentedon Apr 27, 2023
met with the same problem. can't add new flutter module to the native project (more precisely, in projects for each platform iOS and Android).
In my case, the existing native project already has a flutter module that was developed in 2020. This module has been working all these years and for now does not require changes and improvements.
Now the new part of the project is implemented in a separate new flutter module.
The team that developed the first module in the past and the team that is currently developing the second module are different people.
The code is different, the versions of the libraries are different.
It seems that we will need to update the old module, combine both modules under the umbrella project. and connect this module to projects. are there no other options, right?
PS Flutter modules are connected to the project as artifacts. If we talk about android, the host project pulls up the repository with aar.
tong-k-k commentedon Sep 18, 2023
May I ask does flutter now still not support adding more than 1 flutter module to native?
I am just trying to add more than 1 module to ios but it seems I cannot do this in pod file.
Thanks
AlvBarros commentedon Sep 21, 2023
I think so, @tong-k-k .
There's a single "Flutter" module and one for every plugin that has native code. And you also have to add them to your GeneratedPluginRegistrant file.
huyphuongas commentedon Mar 27, 2024
Can you share the solution to do it?
I want to add flutter module to flutter app but haven't found a solution yet.
Thanks.
razr130 commentedon Jun 11, 2024
chan150 commentedon Nov 11, 2025
Any solution is here?
We want to import aar flutter module into flutter app.
emakar commentedon Nov 11, 2025
is this related? the issue is about add-to-app (ie. to native app)
why not add flutter to flutter app as a plugin/module?
chan150 commentedon Nov 11, 2025
@emakar
We want to serve a package without publishing our code.
We already have an experienace with add-to-app and it is good solution for native app.
We tested following environment and it is failed since multiple flutter modules are not supported.
There is three projects: flutter module(compiled aar), flutter plugin and flutter app.
Once flutter module is imported then flutter plugin does not work.
emakar commentedon Nov 11, 2025
@chan150 I don't think it's supported - flutter tooling builds single libapp.so
when not publishing code - the only thing one could publish is libapp.so (aar which contains it)
but flutter app as well builts into libapp.so, so there is a conflict
you could likely look into forking libapp load logic though