【问题标题】:Flutter issues with release-mode only APK builds仅发布模式的 APK 构建的颤振问题
【发布时间】:2020-12-25 04:41:44
【问题描述】:

从已安装的 APK 运行应用时,我遇到了问题,但直接从 Android Studio 运行时,应用运行良好。在物理设备和模拟器上进行了测试,还使用构建模式调试、配置文件和发布(其中发布和配置文件模式当然只适用于物理设备)

总结: a) Shared Prefs、Path Provider 和 Permission Handler 产生一个MissingPluginException。 b) Android 后退按钮不起作用。

这些可能是单独的问题,但我强烈怀疑它们是相关的,因为它们仅在应用程序从未直接从 Android Studio 安装的 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:lintVitalRelease 而不是 :app:lintVitalQaRelease 我得到的。此外,错误将在报告的情况下将缺少的中间体显示为.../flutter/Profile/libs.jar,同样没有味道。

就我而言,额外的Qadev 分别是两种不同的风格。在其他情况下,解决方法是“构建您的调试和配置文件模式 apk 以解决问题”,在我的情况下,它是“构建您的调试和配置文件并发布适用于所有其他风格的 APK,而不仅仅是您正在尝试的那个建造”。

所以我在尝试构建风味“Qa”模式“发布”和它抱怨的任何一个之间切换,一遍又一遍,直到它满意并生成 APK。不得不构建一堆不相关的风格和模式很烦人,但至少是一种让我获得 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 的权限处理程序示例。我刚刚将它作为一个新的“页面”添加到我的应用程序中。在导航到此页面时,我得到另一个异常:

MissingPluginException(No implementation found for method checkPermissionStatus on channel flutter.baseflow.com/permissions/methods)

应用程序中与这些插件相关的许多功能都不起作用 - 照片不显示,用户需要在每次重新启动时进行身份验证,等等。这些显然依赖于上述插件。

我尝试将 WRITE_EXTERNAL_STORAGE 添加到 AndroidManifest,甚至将其添加到每种口味的单独清单中。 (我通常只将共享配置添加到主 AndroidManifest.xml)

我已经为发布模式实现了签名,以防 Android 不喜欢授予未签名 APK 的权限。

编辑: 为了消除应用程序 ID 作为问题的原因,我已将所有实例更改回创建项目时使用的原始包名称。这意味着一次只能在我的设备上安装一种风格。然而,它没有任何区别。


我显然已经做了很多次flutter-clean和flutter-get,每次都强迫我一个一个地构建所有缺少的中间体的过程。

还有一件事……Android 后退按钮不起作用。如果我直接从 Android Studio 运行该应用程序,它工作正常,但仅从 APK 运行它时不起作用(似乎被忽略)。

我对此束手无策。

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

我也设置了应用图标。

复制源代码很费力 - 有很多很多的导入,但最终结果是一个有效的构建。

SharedPrefs 在重启后仍然存在 显示下载的图像 Android后退按钮有效 存储设备权限显示为已授予 从应用程序内打开相机第一次请求许可。 该应用可以将用户引导至 Android 应用设置屏幕。

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

接下来的步骤是签署 APK,然后重新引入风味,即使只是为了能够设置 dart 目标,但也希望能够设置其他属性。

【问题讨论】:

  • 我开始怀疑这与 AppicationID / 包名称有关。每个“风味”在 app/build.gradle 中都有不同的 applicationID。这些通常与对应的 AndroidManifest.xml 中的风味特定包名称匹配。问题是 Kotlin mainActivity 中还有一个名称与创建项目时的原始包名称相关,而主 AndroidManifest 中还有另一个名称。 xml。存在冲突,我认为这会引起问题。我不知道如何解决这些问题。
  • 我更改了所有风格和构建模式以使用原始 packageID。这意味着我一次只能安装一种风格,但是它不起作用,我仍然遇到同样的问题。
  • 检查你的职业后卫。它是一个乱七八糟的人。

标签: android flutter build.gradle release


【解决方案1】:

我遇到了这个确切的问题。我用几种不同的方法解决了它:

  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 中通过导航到 SDK 管理器->SDK 工具->检查和下载 Google Play 服务将 android 迁移到 AndroidX

  2. 我还确保编译 SDK 和目标 SDK 是 29;目前 SDK 30 的 permission_handler 包存在问题。

  3. 我还编辑了 kotlin 主活动文件:

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);
    }
}

【讨论】:

    【解决方案2】:

    对我来说,这解决了问题

    只需将 proguard-rules.pro 添加到 android/app/proguard-rules.pro

    并添加以下行:

    -keep class androidx.lifecycle.DefaultLifecycleObserver
    

    【讨论】:

      【解决方案3】:

      正如@Alex 所回答的,Flutter 会混淆代码,有时它会在 Android 或 Java 库上产生错误。

      我建议您阅读下面的这篇文章并尝试将缺少的类添加到“proguard-rules”中: https://medium.com/@swav.kulinski/flutter-and-android-obfuscation-8768ac544421

      【讨论】:

        猜你喜欢
        • 2020-12-30
        • 2020-07-07
        • 2022-07-12
        • 2020-04-22
        • 2021-04-14
        • 2022-01-01
        • 2020-08-25
        • 2020-12-18
        • 2021-11-16
        相关资源
        最近更新 更多