Flutter安卓5.1/6.0/7.0正式版崩溃:Display.getSize空指针异常
根因分析
从你提供的崩溃栈可以看到,空指针出现在org.chromium.ui.display.DisplayAndroid.updateFromDisplay方法中,虽然你没有直接引入Flutter WebView插件,但该问题触发的核心原因如下:
- 项目依赖的某款第三方插件隐性调用了系统WebView能力(常见的有广告插件、统计插件、用户反馈插件、设备信息采集类插件),底层加载了Chromium内核
- Release模式默认开启R8代码混淆,裁剪了Chromium内核中对Display对象的非空校验逻辑,Android 5.1~7.0版本的系统存在DisplayManager回调时序问题,屏幕变化广播触发时Display对象还未完成初始化,直接调用
getSize方法就会抛出空指针 - Debug模式默认关闭代码混淆,保留了所有非空校验逻辑,因此不会触发崩溃
解决方案
方案1:添加混淆规则(优先尝试,适配绝大多数场景)
在Android项目的proguard-rules.pro文件中添加如下规则,禁止裁剪Chromium相关逻辑:
# 保护Chromium相关代码不被混淆裁剪 -keep class org.chromium.** { *; } -keep @org.chromium.base.annotations.JNINamespace class * { *; }
添加规则后重新打Release包验证即可。
方案2:排查隐性依赖WebView的第三方插件
如果添加混淆规则后问题仍然存在,按以下步骤排查问题插件:
- 执行
flutter pub deps命令输出完整依赖树 - 重点排查非官方维护的广告、统计、H5加载类插件,这类插件大概率内置WebView能力
- 临时移除可疑插件后打Release包验证,定位到问题插件后可更换为同类型无WebView依赖的插件,或向插件开发者提交适配需求
方案3:提前初始化WebView规避时序问题
如果你的应用必须兼容Android 7.0以下系统,可在MainActivity初始化阶段提前创建WebView实例,修复系统回调时序问题:
Kotlin版本示例(MainActivity.kt):
import android.os.Build import android.webkit.WebView import androidx.annotation.RequiresApi import io.flutter.embedding.android.FlutterActivity class MainActivity : FlutterActivity() { @RequiresApi(Build.VERSION_CODES.LOLLIPOP_MR1) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Android 7.0及以下提前初始化WebView if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) { WebView(this) } } }
Java版本示例(MainActivity.java):
import android.os.Build; import android.os.Bundle; import android.webkit.WebView; import androidx.annotation.RequiresApi; import io.flutter.embedding.android.FlutterActivity; public class MainActivity extends FlutterActivity { @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Android 7.0及以下提前初始化WebView if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) { new WebView(this); } } }
内容的提问来源于stack exchange,提问作者Faiz Hashmi
相关产品推荐
相关产品推荐

