Flutter发布模式下APK构建问题

8

当我从已安装的APK中运行应用程序时,出现了问题,但当直接从Android Studio运行应用程序时,应用程序可以正常工作。在物理设备和模拟器上进行测试,并使用构建模式debug、profile和release(其中release和profile模式当然只适用于物理设备)。

总结: a)Shared Prefs、Path Provider和Permission Handler会产生 MissingPluginException。 b)Android返回按钮不起作用。

这些可能是不同的问题,但我强烈怀疑它们之间存在关联,因为它们都仅在从APK启动应用程序时才会发生。

非常清楚的是 - 如果我从Android Studio内部“安装”应用程序,那么即使没有AS连接,我也可以继续使用该应用程序。然而,当我构建一个APK,手动安装并尝试运行应用程序时,就会出现由以上错误引起的各种症状。如果我通过Android Studio连接Logcat,则这些问题将持续存在,直到我使用AS安装新版本为止。

一些更多的细节:

  1. 在发布模式下的APK构建过程中,gradle会抱怨缺少“libs.jar”文件,例如:
Execution failed for task ':app:lintVitalQaRelease'.                    
> Could not resolve all artifacts for configuration ':app:devProfileRuntimeClasspath'.
   > Failed to transform libs.jar to match attributes {artifactType=processed-jar, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime}.
      > Execution failed for JetifyTransform: /home/johan/AndroidStudioProjects/teacher_app/build/app/intermediates/flutter/devProfile/libs.jar.
         > Transform's input file does not exist: /home/johan/AndroidStudioProjects/teacher_app/build/app/intermediates/flutter/devProfile/libs.jar. (See https://issuetracker.google.com/issues/158753935)


搜索解决方案时会出现几个已记录的案例,但通常没有Flavors,因此我得到的是:app:lintVitalQaRelease而不是:app:lintVitalRelease。此外,在报告的案例中,错误将显示缺少的中间件,例如.../flutter/Profile/libs.jar,同样没有Flavors。
在我的情况下,额外的Qadev分别是两种不同的flavor。在其他情况下,解决方法是“构建调试和配置文件模式apk以解决问题”,而在我的情况下,解决方法是“为所有其他flavor构建调试、配置文件和发布APK,而不仅仅是你尝试构建的那一个”。
所以我不断地在"Qa"模式"release"或其它它反复尝试构建,直到满足要求并生成APK。虽然必须构建一堆无关的flavor和模式很烦人,但至少这是一个可以得到APK的解决方法。
此后,我能够安装和运行APK,但存在问题。logcat显示一些MissingPlugin异常: MissingPluginException(No implementation found for method getApplicationDocumentsDirectory on channel plugins.flutter.io/path_provider) 和... MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences) 最后: 在调查所有这些问题时,我尝试了https://pub.dev/packages/permission_handler/example中的permission handler示例。我将其添加为我的应用程序中的新“页面”。当导航到此页面时,我会收到另一个异常: MissingPluginException(No implementation found for method checkPermissionStatus on channel flutter.baseflow.com/permissions/methods) 与这些插件相关的应用程序中许多功能都无法工作——照片不显示,用户需要在每次重新启动时进行身份验证等等。这些明显依赖于上述插件。
我尝试向AndroidManifest中添加WRITE_EXTERNAL_STORAGE权限,甚至将其添加到每个flavor的单独清单中。(通常只将共享配置添加到主AndroidManifest.xml中)
我已经实现了发布模式下的签名,以防Android不喜欢给未签名的APK授予权限。
编辑: 为了排除应用程序ID是问题的原因,我将所有实例更改回创建项目时使用的原始包名称。这意味着一次只能安装一个flavor,但它并没有任何区别。
我显然已经多次执行了flutter-clean和flutter-get,每次都必须强制逐个构建所有缺少的中间文件。

另外还有一件事……Android的返回按钮无法正常工作。如果我直接从Android Studio运行应用程序,它可以正常工作,但是当仅从APK运行时无效(似乎被忽略)。

我已经束手无策了。

编辑#2:取得了进展!
我创建了一个新项目,并复制了源代码(lib / *)。 我还复制了pubspec.yaml和资产。 我没有对build.gradle文件进行任何更改,只对主要的AndroidManifest.xml进行了两个更改-应用程序名称和添加了Internet权限。

我还设置了应用程序图标。

将源代码复制过去是艰难的 — 有许多导入但最终结果是构建成功。

SharedPrefs在重启后仍然存在 下载的图像会显示 Android返回按钮有效 存储的设备权限显示为已授予 从应用程序中打开相机第一次会请求权限。 应用程序可以将用户发送到Android应用程序设置屏幕。

一切似乎都正常工作。 我可能犯了错误,因为新的应用程序在主屏幕上显示正确的应用程序图标,但在应用程序的Android设置页面中显示Flutter默认图标。

下一步将是签署APK,然后重新引入Flavors,即使只是为了能够设置dart目标,但希望还可以设置其他属性。


我开始怀疑这与ApplicationID /包名有关。每个“flavor”在app/build.gradle中都有不同的applicationID。这些通常与相应的AndroidManifest.xml中特定于flavor的包名匹配。问题是,在创建项目时,Kotlin mainActivity中还有一个与原始包名相关的名称,以及主要AndroidManifest.xml中的另一个名称。存在冲突,我认为这会导致问题。我不知道如何解决这些问题。 - The Tahaan
我已将所有口味和构建模式更改为使用原始的packageID。这意味着我一次只能安装一个口味,但不幸的是它并没有起作用,我仍然遇到了同样的问题。 - The Tahaan
检查一下你的ProGuard,它可能是搞鬼的罪魁祸首。 - Jaswant Singh
3个回答

6

我曾经遇到过这个问题。我用了几种不同的方法来解决它:

  1. 将proguard-rules.pro添加到android/app/proguard-rules.pro文件中
#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.**  { *; }
-keep class androidx.lifecycle.** { *; } #https://github.com/flutter/flutter/issues/58479
#https://medium.com/@swav.kulinski/flutter-and-android-obfuscation-8768ac544421
  1. 在应用级别的build.gradle中的buildTypes中添加proguard
buildTypes {
    release {
        profile {
            matchingFallbacks = ['debug', 'release']
        }
    minifyEnabled true
    useProguard true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    signingConfig signingConfigs.release
    }
}
lintOptions {
    disable 'InvalidPackage'
    checkReleaseBuilds false
}
  1. 你也可以尝试在终端中运行主渠道:
flutter channel master
  1. 我在Android Studio中迁移了Android项目到AndroidX,方法是导航到SDK管理器->SDK工具->勾选并下载Google Play服务。

  2. 我还确保编译SDK和目标SDK为29;目前在SDK 30上使用permission_handler软件包可能会出现问题。

  3. 我还编辑了Kotlin主activity文件:

package yourpackage
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
    }
}

1

对我来说,这解决了问题。

只需将proguard-rules.pro添加到android / app / proguard-rules.pro中即可。

并添加以下行:

-keep class androidx.lifecycle.DefaultLifecycleObserver

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接