App requires Multidex support Multidex support is required for your android app to build since the number of methods has exceeded 64k

flutter android 报错 64k

!] App requires Multidex support Multidex support is required for your android app to build since the number of methods has exceeded 64k. See https://docs.flutter.dev/deployment/android#enabling-multidex-support for more information. You may pass the --no-multidex flag to skip Flutter's multidex support to use a manual solution. Flutter tool can add multidex support. The following file will be added by flutter: android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java

主要是 App 启动 MultiDex 主要是为了解决 “65535 方法数超标

  • 当 App 的功能越来越丰富、使用的库越来越多时,其包含的 Java 方法总数也越来越多,这时候就会出现 65535 问题。
  • 在构建 apk 的时候限制了一个 dex 文件能包含的方法数,其总数不能超过 65535(则 64K,1K = 2^10 = 1024 , 64 * 1024 = 65535)。
  • MultiDex, 顾名思义,是指多 dex 实现,大多数 App,解压其 apk 后,一般只有一个 classes.dex 文件,
  • 采用 MultiDex 的 App 解压后可以看到有 classes.dex,classes2.dex,… classes(N).dex,这样每个 dex 都可以最大承载 64k 个方法,很大限度地缓解了单 dex 方法数限制。

LinearAlloc 问题

  • 现在这个问题已经不常见了,它多发生在 2.x 版本的设备上,安装时会提示 INSTALL_FAILED_DEXOPT。
  • 这个问题发生在安装期间,在使用 Dalvik 虚拟机的设备上安装 APK 时,会通过 DexOpt 工具将 Dex 文件优化为 odex 文件,
  • 即 Optimized Dex,这样可以提高执行效率 (不同的设备需要不同的 odex 格式,所以这个过程只能安装 apk 后进行)。
  • LinearAlloc 是一个固定大小的缓冲区,dexopt 使用 LinearAlloc 来存储应用的方法信息,在 Android 的不同版本中有 4M/5M/8M/16M 等不同大小,
  • 目前主流 4.x 系统上都已到 8MB 或 16MB,但是在 Gingerbread 或以下系统(2.2 和 2.3)LinearAlloc 分配空间只有 5M 大小的。
  • 当应用的方法信息过多导致超出缓冲区大小时,会造成 dexopt 崩溃,造成 INSTALL_FAILED_DEXOPT 错误。

处理办法

  • 启用 MultiDex 解决问题
android {
    namespace "com.example.flutter_tv"
    compileSdkVersion flutter.compileSdkVersion
    ndkVersion flutter.ndkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.flutter_tv"
        // You can update the following values to match your application needs.
        // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
        minSdkVersion flutter.minSdkVersion
        targetSdkVersion flutter.targetSdkVersion
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName

        multiDexEnabled true // // Enable MultiDex.
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }
    }
}

在代码里启动 MultiDex

  • 使用 MultiDexApplication。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="xxx">
    <application
        ...
        android:name="android.support.multidex.MultiDexApplication">
        ...
    </application>
</manifest>
  • Application#attachBaseContext(Context)
public class MyApplication extends Application {
	protected void attachBaseContext(Context base) {
		super.attachBaseContext(base);
		MultiDex.install(this); // Enable MultiDex.
	}
}
NoClassDefFoundError
  • 如果你在调用 MultiDex#install(Context) 做了别的工作,而这些工作需要用到的类却存在于别的 dex 文件里面(Secondary Dexes),就会出现类找不到的运行时异常。
  • 正确的做法是把这些需要用到的类标记在 multidex.keep 清单文件里面,再在 build.gradle 里面启用该清单文件。
android {

  defaultConfig {
    multiDexEnabled true
    multiDexKeepProguard file('multidex.pro')
   }
}

dependencies {
  compile'com.android.support:multidex:1.0.1'
}
posted @ 2024-02-01 09:52  vx_guanchaoguo0  阅读(172)  评论(0编辑  收藏  举报