一部の Flutter Android モデルにリリース パッケージをインストールした後、ランダムな黒い画面が表示される

開発とデバッグの初期段階では、デバッグ パッケージは実機上で常に実行されており、ランダムな黒い画面の問題は見つかりませんでしたが、リリース パッケージの準備後、一部の Android モデルでランダムな黒い画面の問題が発生する可能性があります。情報を確認した後、理由は次のとおりです。

1. 混乱 (未解決):

次の設定を android/app/build.gradle ファイルに追加します。

buildTypes {
    release {
        minifyEnabled false //关闭混淆
        shrinkResources false //删除无用资源
        signingConfig signingConfigs.release
        ...
    }
}

2. R8 圧縮をオフにして、D8 圧縮 (未解決) を使用します。

android/gradle.properties ファイルに追加します

# 开启D8压缩
android.enableD8=true
# 关闭R8压缩
#android.enableR8=true

上記の方法を試しても問題は解決しませんでしたが、Android と Flutter のライフサイクルが矛盾していないか考えてみましょう。プロジェクトはfishreduxフレームワークを使用していますか?

Android ネイティブのライフ サイクルを android/app/src/main/kotlin/.../MainActivity.kt ファイルに書き込みます。再コンパイルすると、このファイルは Android ネイティブと接続していないため実行されないことがわかります。 、そのため、実行されなかった具体的な詳細の理由は明らかではありませんが、ライフサイクルの不一致とは何の関係もありません。

Flutter のネイティブな書き込みメソッドでページを置き換える場合、fishredux は使用されず、再コンパイルしても問題は解決されません。

この問題は 1 週間以上ずっと頭を悩ませています。エラーを報告しないと問題を見つけることができず、リリースによって要点が中断されることもありません。少し絶望しています。最後に、これだけでは不十分だと思います。リファクタリング?依存関係の設定や環境に問題があるのでしょうか?この場合、片方の依存関係だけを頼りにしてもう片方を確認し、環境を再セットアップして問題がどこにあるのかを確認するしかありませんが、オンラインに行く時間がたくさんあると本当に泣きたくなります...。

最初に依存関係の問題かどうかを確認しました。Flutter は新しいプロジェクトを作成し、元のプロジェクトの依存関係を順番に導入しました。依存関係には問題がないことがわかりましたが、新しいプロジェクトがリリースされたときに黒い画面の問題は発生しませんでした。元のプロジェクトとの違いは入り口のメインファイルが異なるだけなので、新しいプロジェクトのメインファイルを元のプロジェクトに置き換えれば、リリースを押した後の黒い画面は表示されなくなり、OK! メインファイルに問題があるのです!

問題の原因は以下の通りです!解決!

メインファイルには次のようなコードがあります。

window.physicalSize は画面のサイズを監視し、画面が空でない場合は window.onMetricsChanged コールバックを実行します。

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

このコードの問題ではないかと思い、この段落の論理判定をすべてコメントアウトし、runApp だけを残して再コンパイルしたところ、黒い画面は出なかったものの、ランダムなページ乱れが発生しました。

黒い画面とページが混乱する理由は、起動を高速化するために、画面サイズがまだ空のときにフラッターがページをレンダリングするためです。runApp を確認する前に、まず WidgetsFlutterBinding.ensureInitialized() を実行して、WidgetsFlutterBinding のインスタンスがあることを確認する必要があります。上記のコードを次のように変更します。

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

void runMyApp() async{
    WidgetsFlutterBinding.ensureInitialized();
    runApp(MyApp());
}

コンパイル後も問題は解決されません。Stack Overflow の誰かが同じ問題に遭遇し、次のコードを提供しました。

import 'dart:async';
import 'dart:ui';
import 'package:flutter/widgets.dart';

Future<void> waitScreenSizeAvailable() async {
  if (!_hasScreenSize) {
    WidgetsFlutterBinding.ensureInitialized();
    var observer = _Observer();
    WidgetsBinding.instance.addObserver(observer);
    await observer.hasScreenSize;
    WidgetsBinding.instance.removeObserver(observer);
  }
}

bool get _hasScreenSize => !window.physicalSize.isEmpty;

class _Observer extends WidgetsBindingObserver {
  final _screenSizeCompleter = Completer<void>();

  Future<void> get hasScreenSize => _screenSizeCompleter.future;

  @override
  void didChangeMetrics() {
    if (!_screenSizeCompleter.isCompleted && _hasScreenSize) {
      _screenSizeCompleter.complete();
    }
  }
}

メイン ファイルのコードを次のように変更します。

if(window.physicalSize.isEmpty){
    window.onMetricsChanged = () async {
        //在回调中,size仍然有可能是0
        if(!window.physicalSize.isEmpty){
            window.onMetricsChanged = null;
            await waitScreenSizeAvailable(); //引入上面那段代码
            runMyAPP();
        }
    };
} else{
    //如果size非0,则直接runApp
    await waitScreenSizeAvailable(); //引入上面那段代码
    runMyAPP();
}

コンパイル後、問題は解決しました。

この問題は前後 2 週間近くスタックしています。プロセス全体でエラー メッセージが表示されないため、問題の場所を特定することはできません。また、リリースではポイントを中断できないため、どこで問題が発生しているかを盲目的に推測することしかできません。問題がある可能性があるので、段階的に調査してください。でも、ようやく解決して、涙が溢れてきました…。

おすすめ

転載: blog.csdn.net/YML_426/article/details/129730925