flutter 编译报错总结(不断更新)

1、Cannot fit requested classes in a single dex file

问题

Cannot fit requested classes in a single dex file (# methods: 66370 > 65536)

原因分析

主要原因是你的项目貌似有点大,已经超过65k个方法。一个dex已经装不下了,需要个多个dex,也就是multidex ,因为Android系统定义总方法数是一个short int,short int 最大值为65536。

解决方案

  1. 在app module中的build.gradle中添加依赖
    implementation 'com.android.support:multidex:1.0.3' 
    //
    dependencies {
        implementation fileTree(include: ['*.jar'], dir: 'libs')
        implementation 'com.android.support:appcompat-v7:28.0.0'
        implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
        //添加到此处
        implementation 'com.android.support:multidex:1.0.3'
    }
  2. 在app module中的build.gradle中的defaultConfig中添加以下代码
    android {
        compileSdkVersion 28
        defaultConfig {
            applicationId "com.example.demo"
            minSdkVersion 16
            targetSdkVersion 28
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
            //添加到此处
            multiDexEnabled true
        }
    }

2、Flutter在profile和release模式下的白屏问题

import 'dart:ui';//window需要import ui库

void main(){
  //如果size是0,则设置回调,在回调中runApp
  if(window.physicalSize.isEmpty){
    window.onMetricsChanged = (){
      //在回调中,size仍然有可能是0
      if(!window.physicalSize.isEmpty){
        window.onMetricsChanged = null;
        runApp(MyApp());
      }
    };
  } else{
    //如果size非0,则直接runApp
    runApp(MyApp());
  }
}

分析

这段代码里有两个东西需要了解一下的,第一个是window.onMetricsChanged,源码的注释是这样写的

/// A callback that is invoked whenever the [devicePixelRatio],\
/// [physicalSize], [padding], or [viewInsets] values change, for example\
/// when the device is rotated or when the application is resized (e.g. when\
/// showing applications side-by-side on Android).

也就是当devicePixelRatio、physicalSize、padding、viewInsets这几个东西变化时会触发的回调,其中屏幕大小就是physicalSize

第二个是physicalSize,上面说了这个是屏幕大小,但是它一开始是0*0,直到Flutter初始化时将它赋值为屏幕大小才能获取到非0的值

好了,说完了上面两个东西,就来说说问题。问题的坑点在于,mian()方法并不是在Flutter给physicalSize赋值后才运行的,两者并没有固定的先后顺序,从测试来看,跟设备的性能有关

之前的错误解法

之前是下面这样写的,然后在新ipad air的profile模式下以及所有机型的debug模式下都会白屏,只有比较旧的mini4不会白屏

void main(){
  window.onMetricsChanged = (){
    runApp(MyApp());
    window.onMetricsChanged = null;
  };
}

经排查,发现原因是mini够慢,在设置了onMetricsChanged回调后flutter还没有读取到屏幕size,也就还没出触发onMetricsChanged。

然而在新air上,则是几率性的,有时和mini一样,有时在设置onMetricsChanged之前flutter就已经读取了屏幕size了,所以后面一段时间都不会触发onMetricsChanged,导致白屏。更奇怪的是,有时设置的onMetricsChanged倍触发后,仍然是白屏,排查后发现air上不止一次resize,而只有最后一次非0。

所以完整的代码中有这一段保护:

window.onMetricsChanged = (){
  //这里仍然有可能是0
  if(!window.physicalSize.isEmpty){
    window.onMetricsChanged = null;
    runApp(MyApp());
  }
};

链接:https://www.jianshu.com/p/4f0651241956\

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!