I tried using the flutter_tflite: ^1.0.1
package to build a real-time object detection app. Everything worked fine when I tested it on the emulator. However, when I tried to build it into an APK and app bundle, the following error occurred:
Execution failed for task ':flutter_tflite:verifyReleaseResources'.
> A failure occurred while executing com.android.build.gradle.tasks.VerifyLibraryResourcesTask$Action
> Android resource linking failed
ERROR: /Users/baka/Documents/Application/llenn/myappku/build/flutter_tflite/intermediates/merged_res/release/mergeReleaseResources/values/values.xml:194: AAPT: error: resource android:attr/lStar not found.
app/build.gradle
plugins {
id "com.android.application"
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
}
android {
namespace = "com.example.myappku"
compileSdk = 35
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
signingConfigs {
release {
keyAlias = "sipisang"
keyPassword = "Bakachi2024"
storeFile = file("/Users/baka/Documents/aplikasi/keystore/sipisang.jks")
storePassword = "Bakachi2024"
}
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.myappku"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = 23
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
minifyEnabled true
// useProguard true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig = signingConfigs.release
}
}
aaptOptions {
noCompress 'tflite'
noCompress 'lite'
}
}
flutter {
source = "../.."
}
gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
settings.gradle
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.1.4" apply false
id "org.jetbrains.kotlin.android" version "2.0.21" apply false
}
include ":app"
android/build.gradle
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = "../build"
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(":app")
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
flutter doctor
What can I try next?
In android/app/build.gradle, add the following setting in the android block.
aaptOptions {
noCompress 'tflite'
noCompress 'lite'
}
So you have to configure your app/build.gradle into:
plugins {
id "com.android.application"
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
}
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
namespace = "com.example.myappku"
compileSdk = flutter.compileSdkVersion
ndkVersion = "27.0.12077973"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.myappku"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
signingConfigs {
release {
keyAlias = keystoreProperties['keyAlias']
keyPassword = keystoreProperties['keyPassword']
storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword = keystoreProperties['storePassword']
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.release
}
}
aaptOptions {
noCompress 'tflite'
noCompress 'lite'
}
}
flutter {
source = "../.."
}
Then rebuild your project.
Please consider this version matrix based on the Android Studio version:
Here's the source.
Here's what I perform to resolve the exception:
Execution failed for task ':app:minifyReleaseWithR8'
Add this to your proguard-rules.pro
file:
# Ignore Play Core dynamic features if not used
-dontwarn com.google.android.play.core.**
-dontwarn io.flutter.embedding.engine.deferredcomponents.**
# Prevent R8 from removing these classes (if referenced)
-keep class com.google.android.play.core.** { *; }
-keep class io.flutter.embedding.engine.deferredcomponents.** { *; }
Before building a release build of an APK, I perform these commands first:
flutter clean
flutter pub get
cd android
./gradlew build
Here's what I've got:
PS C:\path_to_your_app\android> flutter build apk --split-per-abi Changing current working directory to: C:\path_to_your_app
Font asset "MaterialIcons-Regular.otf" was tree-shaken, reducing it from 1645184 to 1384 bytes (99.9% reduction). Tree-shaking can be disabled by providing the --no-tree-shake-icons flag when building your app. Running Gradle task 'assembleRelease'...
21.4s √ Built build\app\outputs\flutter-apk\app-armeabi-v7a-release.apk (11.2MB) √ Built build\app\outputs\flutter-apk\app-arm64-v8a-release.apk (13.8MB) √ Built build\app\outputs\flutter-apk\app-x86_64-release.apk (14.9MB)
Add first your proguard-rules.pro file, if it is not yet added to your project.
In your Android Studio, right-click on the app directory, select New > File, then type proguard-rules.pro
to add the file.
Here's my build configuration:
#Flutter Wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
# Ignore Play Core dynamic features if not used
-dontwarn com.google.android.play.core.**
-dontwarn io.flutter.embedding.engine.deferredcomponents.**
# Prevent R8 from removing these classes (if referenced)
-keep class com.google.android.play.core.** { *; }
-keep class io.flutter.embedding.engine.deferredcomponents.** { *; }
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.1.4" apply false
id "org.jetbrains.kotlin.android" version "2.0.21" apply false
}
include ":app"
plugins {
id "com.android.application"
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
}
android {
namespace = "com.example.flutter_build_ref"
compileSdk = 35 // flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
signingConfigs {
release {
keyAlias = "dummyKeyAlias"
keyPassword = "dummypw"
storeFile = file("C:/your_predefined_path/dummyKeyStore/keystore.jks")
storePassword = "dummypw"
}
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.flutter_build_ref"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = 23 // flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
minifyEnabled true
// useProguard true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig = signingConfigs.release
}
}
aaptOptions {
noCompress 'tflite'
noCompress 'lite'
}
}
flutter {
source = "../.."
}
NOTE: For testing purposes, I've decided to create a dummy key store.
I am using Android Studio Koala | 2024.1.1, but you can test my build in your updated Android Studio version (only if introduce other exception).
To answer the question,
Does the version of Java also have an impact?
Here's the reference:
Source: Compatibility Matrix.
Note: Based on my observation while dealing with gradle, kotlin, and java compatibilities. You have to understand what is the meaning of the exception logs coming from your app, before you adjust your certain tools version. Don't forget to perform cleaning of caches while you are having struggles with your build. Sometimes, it introduces conflict with the cache build. Restarting your Android Studio IDE isn't always necessary.
Tips: always read official tools documentation from which you are dealing with.
Here's the supporting reference to somehow help you to deal with build issues.
I hope it helps!