How to use --dart-define in a Flutter app embdedded in Android - flutter

I'm Embedding a Flutter app as a module within an existing Android app (https://flutter.dev/docs/development/add-to-app/android/project-setup) and would like to know if/how I can use "--dart-define" to define compile-time constants. Tried using ./gradlew -Ddart-define=myVal=Value without any luck.
When building a typical Flutter app I would use the flutter command. In my case I'm continuing to use gradlew to build my app and it's unclear how to pass in --dart-define constants.

In android studio you may edit running configuration (press drop-down near "run" button -> "Edit configurations...") and define variables there ("Additional run args:" row):
--dart-define="http_serv=http://10.0.2.2:42627/" --dart-define="websocket=ws://10.0.2.2:42627/websocket"
Getting variable in code:
final checkArgs = String.fromEnvironment('http_serv', defaultValue: '');

If your project depends on the Android Archive (AAR).
You can pass the dart-defines in the command line.
flutter build aar --dart-define=myVal=Value
If your project depends on the module’s source code.
You can set dart-defines in gradle.properties in your android host project directory (or in yourHostProject/yourFlutter/.android/Flutter/ directory).
--dart-define=myVal=Value
Explanation
.android/Flutter/build.gradle script executes "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" script. When the flutter.gradle is executed, your dart files are compiled into naitive code.
flutter.gradle loads dart-defines from the .android/Flutter project instance (flutter.gradle#731-L734) and then, use it ( flutter.gradle#L1091-L1093).
To set the project instance value, you add --dart-define=myVal=Value into gradle.properties. (If you have multiple gradle.properties files, consider configuration order(Gradle properties in Gradle Docs).

Related

After flutter new project creation I can't locate the main dart file to start programming

I have installed Android Studio and flutter successfully. When I run flutter doctor in command prompt it gives me [all green ticks in these brackets].
The question is that after the creation of a new flutter project on the right-hand side of the screen under the project I am unable to see/locate any dart main file to write code. For further clarification, you can see the attached image below.
Unable to locate the dart file to write code in the project hierarchy:
I have 0 ideas what is still missing in the configuration of Flutter / Android Studio
Well, I figured out why pubspec.yaml and main.dart was not in my project due to the older version of flutter. I downloaded the latest version flutter_windows_2.2.2-stable, created a new flutter project, and included the flutter SDK path of flutter_windows_2.2.2-stable which resolved all my problems. Kindly, make sure whoever wants to start Mobile Application development in Android Studio + Flutter + Dart always download the latest version of everything.
Recent Experiment:
After downloading the latest version of Flutter still, I was unable to get the pubspec.yaml and main.dart files in my Android Studio Project, so the solution is below:
where you have extracted your flutter_windows_2.2.2-stable remember the directory path like E:\src\flutter_windows_2.2.2-stable which is in my scenario.
******************* CMD WORK *******************
Open cmd(Command Prompt) by default you will be in the directory like C:\Users\UserName\
Now go to the path E:\src and to navigate write E: hit enter, now you will be in the E: directory. Write cd E:\src hit enter.
type flutter create project_name ( make sure whenever you withe the name of the project it should be like this my_first_app in this format you name the projects with proper naming convention in flutter [word_word_word_word] ) then hit enter, wait for a while it will create a new flutter project for you including pubspec.yaml and main.dart files + necessary files to be imported.
Reference for naming convention in flutter (https://medium.com/flutter-community/file-and-folder-structure-in-flutter-967b8be3155e#:~:text=Flutter%20doesn't%20have%20a,letters%20and%20underscores%20between%20words.&text=When%20naming%20folders%2C%20you%20want,them%20very%20direct%20and%20clear.)
Right now after the creation of a project(Flutter) in Android Studio you are unable to see/locate the pubspec.yaml and main.dart files use cmd for the project creation which worked in my scenario.

How Can I disable minify for flutter web release build [duplicate]

flutter build web will build my flutter app with obfuscation and minification.
I want my error stack to be readable though.
How should I modify the command?
Try:
flutter build web --profile --dart-define=Dart2jsOptimization=O0
See:
https://github.com/flutter/flutter/blob/720dff6a94bd054e82ec4bf84b5cb802bbc52ddd/packages/flutter_tools/lib/src/build_system/targets/web.dart#L238-L239
There's an issue on github for this feature, feel free to upvote ;)
https://github.com/flutter/flutter/issues/96283
This is a old post, but I found the answer.
If you build the app with this line:
flutter build web --profile --source-maps
Then when you print a stacktrace, you'll get something like this:
Exception: Hello
at Object.wrapException (js_helper.dart:1123:37)
at _MyHomePageState__incrementCounter_closure.call$0 (main.dart:64:7)
at _MyHomePageState.setState$1 (framework.dart:1114:28)
at _MyHomePageState._incrementCounter$0 (main.dart:57:5)
at tear_off.<anonymous> (js_helper.dart:2099:9)
at _InkResponseState.handleTap$0 (framework.dart:909:26)
at tear_off.<anonymous> (js_helper.dart:2099:9)
at TapGestureRecognizer.invokeCallback$1$3$debugReport (recognizer.dart:253:16)
at TapGestureRecognizer.invokeCallback$2 (recognizer.dart:239:6)
at TapGestureRecognizer.handleTapUp$2$down$up (tap.dart:627:11)
If you use --source-maps with a release build, you will still get the dart file and line number, but the class/method names in the stacktrace will be obfuscated.
And, if you copy the lib directory into the root of built web directory, it will display the source code when you click on the dart file/line number in the stacktrace. Also, you can set breakpoints in the dart code, just like you can do when you do flutter run web.
The only way I have found to do this is to use flutter run -d chrome. We would then need to locate where the files on disk are located.

Trying to generate proto to dart file

I'm trying to generated proto file to dart file with protoc-plugin follow this instruction https://grpc.io/docs/quickstart/dart/ but when I run this command line
protoc --dart_out=grpc:lib/proto --plugin=protoc-gen-dart=C:/src/flutter/flutter/.pub-cache/bin/protoc-gen-dart.bat -Iprotobuf protobuf/utils.proto
And it showed this error:
'dart' is not recognized as an internal or external command,
operable program or batch file.
'pub' is not recognized as an internal or external command,
operable program or batch file.
--dart_out: protoc-gen-dart: Plugin failed with status code 1.
I have installed dart as a plugin in my Android Studio. Is that I have to install dart SDK and add it to environment variable path to work?
Update
It worked after i install dart sdk and restart my pc.
Seeing the Flutter tag, I presume that Flutter SDK was what you had before you install Dart SDK as said in your update.
If you want to do this without having to install Dart SDK separately (since Flutter SDK has Dart SDK within itself already), the environment has to know where the following are at:
Flutter SDK
eg: export PATH="~/desktop/development/flutter/bin:$PATH"
Dart SDK within Flutter SDK
eg: export PATH="~/desktop/development/flutter/bin/cache/dart-sdk/bin:$PATH"
Pub cache within Flutter SDK (where the protoc plugin will be located at)
eg: export PATH="$PATH":"$HOME/desktop/development/flutter/.pub-cache/bin"
The given examples above are from .bash_profile in macOS, but in essence, the environment has to know where these 3 are before trying to globally activate the plugin via flutter pub global activate protoc_plugin and then generate Dart code from proto files.
The file protoc-gen-dart.bat actually has bugs in it. It's trying to run exe called pub which doesn't exist. You need to manually edit the file. It should be
dart pub global run protoc_plugin:protoc_plugin %*
not
pub global run protoc_plugin:protoc_plugin %*
Once I changed this, I was able to generate protos for Dart on Windows

How to do integration testing in Flutter?

I want to do integration testing in Flutter. The tutorial I follow gives the following procedure:
Add the flutter_driver package to pubspec:
dev_dependencies:
flutter_driver:
sdk: flutter
Enable the Flutter driver extension and add a call to
the enableFlutterDriverExtension() function in main.dart.
Run the integration test by using the flutter drive command:
flutter drive --target=my_app/test_driver/my_test.dart
My problem is with understanding step 2. It's not clear to me where in Android Studio do you enable the driver extension and where exactly in main.dart do you call the function enableFlutterDriveExtension().
I also have problems with the third step. After running the said command, it says in my terminal that
Error: The Flutter directory is not a clone of the GitHub project.
The flutter tool requires Git in order to operate properly;
to set up Flutter, run the following command:
git clone -b stable https://github.com/flutter/flutter.git
You have to add this code inside the test_driver/app.dart file.
import 'package:flutter_driver/driver_extension.dart';
import 'package:[YOUR_APP]/main.dart' as app;
void main() {
// This line enables the extension
enableFlutterDriverExtension();
// Call the `main()` function of your app or call `runApp` with any widget you
// are interested in testing.
app.main();
}
You can find more info on the official Flutter documentation site (Steps 3 & 4):
https://flutter.dev/docs/cookbook/testing/integration/introduction
Good luck ;)
In order to run integration test in flutter, you need to create "test_driver" directory inside app root dir. Than you need to create two files inside "test_driver" folder.
Lets call first file "app.dart" and there you need to instrument your app(answer above).
Than you need to create your test file, which needs to be called "app_test.dart" and here you write your actual test code.
When you want to run that test, just run "flutter drive --target=test_driver/app.dart".
About step 3 in your question, check if you set flutter home properly and after adding flutter_driver dependency, run "packages get".

How to obfuscate Flutter apps?

Flutter's wiki mentions obfuscation is an opt-in in release mode.
And yet, the flutter build command has no relevant option - see:
flutter help -v build apk
Am I missing something here?
Did they make obfuscation the default?
Is obfuscation even relevant for flutter?
Any pointers on this would be very appreciated.
Obfuscation is needed - a flutter app knows its function names, which can be shown using Dart's StackTrace class. There's under-tested support for obfuscation. To enable it:
For Android:
Add to the file [ProjectRoot]/android/gradle.properties :
extra-gen-snapshot-options=--obfuscate
For iOS:
First, edit [FlutterRoot]/packages/flutter_tools/bin/xcode_backend.sh:
Locate the build aot call, and add a flag to it,
${extra_gen_snapshot_options_or_none}
defined as:
local extra_gen_snapshot_options_or_none=""
if [[ -n "$EXTRA_GEN_SNAPSHOT_OPTIONS" ]]; then
extra_gen_snapshot_options_or_none="--extra-gen-snapshot-options=$EXTRA_GEN_SNAPSHOT_OPTIONS"
fi
To apply your changes, in [FlutterRoot], run
git commit -am "Enable obfuscation on iOS"
flutter
(Running "flutter" after the commit rebuilds flutter tools.)
Next, in your project, add following to [ProjectRoot]/ios/Flutter/Release.xcconfig file:
EXTRA_GEN_SNAPSHOT_OPTIONS=--obfuscate
PS: Haven't tried the --save-obfuscation-map flag mentioned at https://github.com/dart-lang/sdk/issues/30524
Again, obfuscation isn't very well tested, as mentioned by #mraleph.
AppBundle (recommended):
Without splitting:
flutter build appbundle --obfuscate --split-debug-info=/<directory>
Splitting:
flutter build appbundle --target-platform android-arm,android-arm64,android-x64 --obfuscate --split-debug-info=/<directory>
APK:
Without splitting:
flutter build apk --obfuscate --split-debug-info=/<directory>
Splitting:
flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi --obfuscate --split-debug-info=/<directory>
PS: About Splitting:
By default, fat apk contains arm v7, arm v8 and x64 which increases apk size, which you don't want to. So, when you split it, you have separate binaries which you can upload on the store and thus reducing the size of the apk that a user would need to download.
All the above answers are correct, but no answer tells you that we need to add a relative path or directory path while generating build.
Example using Relative Path:
flutter build apk --obfuscate --split-debug-info=./ProjectFolderName/debug
Example using Folder Path:
flutter build apk --obfuscate --split-debug-info=/Users/apple/Desktop/items/debug
The above command will generate a build inside the given project directory, it will create a new folder called ProjectFolderName or 'debug' on the respective command, and there you can find the release build.
https://flutter.dev/docs/deployment/obfuscateRefer this link for more info
Note: Flutter’s code obfuscation, Supported as of Flutter 1.16.2.
For Android the process is pretty clear from the doc at https://flutter.dev/docs/deployment/obfuscate. For Example:
export version=1.0.0
flutter build apk --release --shrink --obfuscate --split-debug-info=misc/mapping/${version}
Several files will be created such as misc/mapping/1.0.0/app.android-arm64.symbols (which you'll likely want to keep in VCS)
For iOS it's a bit less obvious since you often use the Xcode menu: Product > Archive
make an obfuscated build for iOS
flutter build ios --release --obfuscate --split-debug-info=misc/mapping/${version}
it creates file misc/mapping/1.0.0/app.ios-arm64.symbols
This will also modify ios/Flutter/Generated.xcconfig to include
DART_OBFUSCATION=true
SPLIT_DEBUG_INFO=misc/mapping/1.0.0
Use Xcode menu: Product > Archive which will uses Release.xcconfig which includes updated Generated.xcconfig
#include "Generated.xcconfig"
So your uploaded Archive will now be obfuscated (you don't need to make changes to Release.xcconfig)
See also - https://github.com/flutter/flutter/issues/64626#issuecomment-736081173
At the moment obfuscation is not directly exposed via the flutter CLI.
You can try to explicitly pass arguements to the gen_snapshot like this:
flutter build --extra-gen-snapshot-options=--obfuscate,--save-obfuscation-map=build/symbols.json --release
Note: that obfuscation support is not very well tested and might not work at the moment.
For iOS edit ios/Flutter/Release.xcconfig
This file should contain something like
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
If you check Generated.xcconfig there is a line DART_OBFUSCATION=false
So add opposite to the end of the Release.xcconfig file to override:
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
DART_OBFUSCATION=true
SPLIT_DEBUG_INFO=obj_maps
You can optionally add TREE_SHAKE_ICONS=true here to tree-shake icons as well