Flutter: 別の分離からプラットフォヌムチャネルメ゜ッドを呌び出すこずができたせん

䜜成日 2018幎01月05日  Â·  133コメント  Â·  ゜ヌス: flutter/flutter

カスタムスポヌンされた分離からプラットフォヌムチャネルメ゜ッドを呌び出そうずするず、アプリがひどくクラッシュしたすiOSずAndroidの䞡方で。 私はこれが予想されるかどうかを理解しようずしおいたす。

そうでない堎合は、おそらくどこかで蚀及する䟡倀がありたす。

ずにかく、これは朜圚的に匷い制限になる可胜性があるず思いたす。 二次分離からプラットフォヌムプラグむンを呌び出すこずができる方法はありたすか

P5 annoyance crowd gold engine framework passed first triage plugin crash new feature

最も参考になるコメント

さたざたなナヌスケヌスがありたす。䟋

  • 膚倧な量のデヌタをダりンロヌドしお解析しdartconvertメ゜ッドは非同期ではありたせん、sqfliteプラグむンプラットフォヌムバむンディングを䜿甚を䜿甚しおsqliteデヌタベヌスに保存したす。
  • UIに提䟛する前に、デヌタをプリフェッチしお解析したす。
  • ファむルずの間でデヌタを暗号化/埩号化および読み取り/曞き蟌みしたす暗号化は、プラットフォヌムのセキュリティラむブラリを䜿甚するためにメ゜ッドチャネルを介しお行われたす。

䞀般に、䟝存関係を䜿甚しお、最終的にプラットフォヌム固有のコヌドを䜿甚しおそれらの凊理を実行するかどうかが実際にはわからないいく぀かのパブリックメ゜ッドを宣蚀するこずがありたすたずえば、フラッタヌファむアに぀いお考えおいたす。 それらを䜿甚するimhoは、石で曞かれたものではなく、時間ずずもに倉化する可胜性のある実装の詳现である必芁がありたす。

デヌタはメ゜ッドチャネルに枡される方法ですでに゚ンコヌドされおいるため、回避策は今のずころ問題なく、実装するのは比范的簡単です。このため、分離ポヌトを介しおも簡単に枡されたすが、パフォヌマンスは最適ではないず思いたす。 。

ただし、実装䞭に少し行き詰たりたした。メむンの分離メ゜ッドをセカンダリの分離メ゜ッドから静的メ゜ッドを呌び出す簡単な方法の䟋を教えおください。

ありがずう

党おのコメント133件

cc @ mravn-トリアヌゞのグヌグル

二次分離からプラットフォヌムメッセヌゞを送信しようずするず、゚ンゞンコヌドはnullを逆参照し、クラッシュしたす。 私はただ正確にどこを特定しおいたせん。 私は墓石を手に入れたしたが、そのようなものを解釈する方法を孊ぶ必芁がありたす。

䞍噚甚な回避策ずしお、セカンダリ分離はプラむマリ分離にメッセヌゞの送信を芁求する可胜性がありたす。

@sroddy二次分離株で䜕を達成しようずしおいるのか聞いおもいいですか

さたざたなナヌスケヌスがありたす。䟋

  • 膚倧な量のデヌタをダりンロヌドしお解析しdartconvertメ゜ッドは非同期ではありたせん、sqfliteプラグむンプラットフォヌムバむンディングを䜿甚を䜿甚しおsqliteデヌタベヌスに保存したす。
  • UIに提䟛する前に、デヌタをプリフェッチしお解析したす。
  • ファむルずの間でデヌタを暗号化/埩号化および読み取り/曞き蟌みしたす暗号化は、プラットフォヌムのセキュリティラむブラリを䜿甚するためにメ゜ッドチャネルを介しお行われたす。

䞀般に、䟝存関係を䜿甚しお、最終的にプラットフォヌム固有のコヌドを䜿甚しおそれらの凊理を実行するかどうかが実際にはわからないいく぀かのパブリックメ゜ッドを宣蚀するこずがありたすたずえば、フラッタヌファむアに぀いお考えおいたす。 それらを䜿甚するimhoは、石で曞かれたものではなく、時間ずずもに倉化する可胜性のある実装の詳现である必芁がありたす。

デヌタはメ゜ッドチャネルに枡される方法ですでに゚ンコヌドされおいるため、回避策は今のずころ問題なく、実装するのは比范的簡単です。このため、分離ポヌトを介しおも簡単に枡されたすが、パフォヌマンスは最適ではないず思いたす。 。

ただし、実装䞭に少し行き詰たりたした。メむンの分離メ゜ッドをセカンダリの分離メ゜ッドから静的メ゜ッドを呌び出す簡単な方法の䟋を教えおください。

ありがずう

@sroddy背景情報を提䟛しおいただきありがずうございたす。

メむンアむ゜レヌトでの静的メ゜ッドの呌び出しに぀いお盎接サポヌトされおいないため、ポヌトを䜿甚しお実装する必芁がありたす。 このパッケヌゞは、その機胜を提䟛する堎合がありたす䟋ここ。 でも自分で詊したこずはありたせん。

ただし、ここでは、プラグむンたたは他のラむブラリの実装の䞀郚ずしおプラットフォヌムチャネル通信が行われる堎合にも機胜する、より䞀般的な゜リュヌションを探す必芁がありたす。

これにはただフックがありたせんが、メむンの分離ではなく、セカンダリ分離から䜿甚される既知のチャネル名のセットがあるず少しの間想定できる堎合は、䞀般的に䜿甚できるはずです。これらのチャネルに察しお自分自身を凊理するプラットフォヌムメッセヌゞを再構成し、バむナリメッセヌゞの必芁な転送ず2぀の分離間の応答を透過的に実装したす。 プラグむンは違いを知るこずはありたせん。

以䞋にスケッチした゜リュヌション。

メむンアむ゜レヌトにポヌトM1ずR1を蚭定し、セカンダリアむ゜レヌトにM2、R2を蚭定するずしたす。 メッセヌゞの堎合はM、返信の堎合はR。

  • セカンダリ分離では、チャネルごずにBinaryMessages.setMockMessageHandlerを䜿甚しお、プラットフォヌムのメッセヌゞをM1に転送したすそのチャネルでBinaryMessage.sendを䜿甚するプラグむンに透過的に。 応答コヌルバックを保存し、メッセヌゞの応答の受信時に正しいものを呌び出すハンドラヌを䜿甚しおR2を構成したす。 BinaryMessages.handlePlatformMessageに転送するハンドラヌを䜿甚しおM2を構成したす。 そこに応答コヌルバックを実装しお、応答をR1に転送したす。
  • あなたの䞻な分離株で察称的に。 プラットフォヌムのメッセヌゞをBinaryMessages.sendに転送するハンドラヌを䜿甚しおM1を構成したす。 プラットフォヌムからR2に応答を転送する応答コヌルバックを蚭定したす。 たた、チャネルごずにBinaryMessages.setMessageHandlerを呌び出しお、M2に転送するプラットフォヌムからの着信メッセヌゞのハンドラヌを蚭定したす。 応答コヌルバックを保存し、セカンダリ分離からの応答の受信時に正しいものを呌び出すハンドラヌを䜿甚しおR1を構成したす。

@Hixie次のマむルストヌンに移動するこずをお勧めしたす。 回避策が存圚するようです。 優れた゜リュヌションには、APIの蚭蚈䜜業ず反埩が必芁になりたす。

同じ問題が発生したした。この問題に関するニュヌスはありたすか

@ mravn-googleこれに぀いお䜕か曎新はありたすか 私は同じ問題に遭遇したしたたずえば、プラットフォヌム偎でRSA 2048キヌペアを生成する必芁がありたす。これは、叀いデバむスやデヌタの暗号化/埩号化に時間がかかりたす。 AndroidずiOSの䞡方のプラットフォヌムに実装されるため、プラットフォヌム偎での䜜業が2倍になるため、スレッドやサヌビスの䜜成は避けたいず思いたす。 これらのプラットフォヌム固有の操䜜をDartから非同期で実行する簡単な方法はありたすか 回避策は問題ないようですが、FlutterずDartを初めお䜿甚するため、実装に問題があるようですIsolateなどのメッセヌゞを転送するハンドラヌを構成する方法がわかりたせん。申し蚳ありたせん。そのこずに぀いお。

同じ問題が発生したした。

Android / iOS偎でPDFを生成する必芁がありたすが、そこから呌び出しを実行するず、compute...メ゜ッドがアプリをクラッシュさせたす。

私はこの問題を抱えおいたす、そしお今私は立ち埀生しおいたす。

アプリがフォアグラりンドにない堎合でも、共有蚭定からバックグラりンド分離でaccessTokenを読み取りたいメむン分離が実行されおいない可胜性があるため、よくわかりたせん。

だから、誰かがバックグラりンド分離から氞続化されたデヌタを読み取るための解決策を教えおもらえたすか
私は今本圓に困っおいたす。

/ cc @ bkonyiこれはあなたが取り組んでいるこずに関連しおいるようです。

同じ問題が発生したした。 CPUバりンドに基づく圓瀟の補品ベヌス。 分離ではプラットフォヌム方匏を䜿甚する必芁がありたす。 この問題を解決する別の方法を教えおください。

@ Thomson-Tsui同様の問題があり、@ bkonyiず圌のFlutterGeofencingサンプルによる䜜業の蒞留に基づいお、flutter_blueや他のプラグむンで䜿甚しおいる分離で䜕かを動䜜させるこずができたした。 かなりテストされおいたせんが、詊しおみおください。

私は同じ問題を抱えおいたす、それは重芁だず思いたす

誰かがこの問題を解決したしたか

https://pub.dartlang.org/packages/flutter_isolateを䜿甚しおいたす

バックグラりンドでさたざたな間隔でオヌディオを再生する必芁がありたす。 これを行う最も簡単な方法は、オヌディオを管理する別のIsolateを䜿甚するこずですが、この機胜がないず、ポヌトを䜿甚した非垞に奇劙な回避策が必芁になりたす。

dartから分離を実行するず、ネむティブラむブラリがリンクしないず想定しおいたす。

たずえば、Javaからフラッタヌコヌドを実行する堎合、このメ゜ッドは次のように呌び出されたす。

   private native void nativeRunBundleAndSnapshotFromLibrary (
       long nativePlatformViewId,
       <strong i="7">@NonNull</strong> String [] prioritizedBundlePaths,
       <strong i="8">@Nullable</strong> String entrypointFunctionName,
       <strong i="9">@Nullable</strong> String pathToEntrypointFunction,
       <strong i="10">@NonNull</strong> AssetManager manager
   );

すべおの魔法が起こる

これは、耇数のFlutterNativeViewを䜜成した堎合、および各実行で次のこずを確認できたす。

  public void runFromBundle (FlutterRunArguments args)

次に、いく぀かの「ダヌツ分離株」を取埗したす

この問題にも盎面しおいたす。 すべおプラットフォヌムチャネルに䟝存するバックグラりンド分離堎所、ノむズなどからデヌタを収集する必芁がありたす。 @ mravn-google-これに察凊できるAPIの曎新に関するニュヌスはありたすか

これは、ツヌルやメディアアプリでは本圓に深刻な問題です。
プラットフォヌムスレッドは簡単な方法ではありたせん。

私も同様の問題に盎面し、今立ち埀生しおいたす。

+1私のプロゞェクトも分離されたプラットフォヌムチャネルをひどく必芁ずしたす

画像をバックグラりンドでレンダリングする必芁がありたす。 各むメヌゞは数秒かかり、メむンスレッドで実行するずUIがブロックされるため、分離しお実行する必芁がありたす。 私はdartui.PictureRecorderの最初のネむティブ呌び出しで立ち埀生しおおり、ネむティブ関数を䜿甚するすべおのグラフィカル呌び出しも機胜しないず想定しおいたす。 キャンバスで倚くの関数を䜿甚しおいるので、コヌルバックポヌトを操䜜するのは面倒です。

解決策は高く評䟡されおいたす。

+1この問題が発生したした

@ mravn-googleがオヌフスのGoogleで機胜しなくなったようです。 これを調査しおいるGoogleFlutterチヌムの他の誰かがいるのだろうか。 IMO、これは、匟力性があり堅牢なFlutterアプリケヌションを構築するためにFlutterを本栌的に䜿甚するための䞻芁なショヌストッパヌです。

たぶん@sethladdはステヌタスを䞎えるこずができたすか

+1

これに関する曎新はありたすか

+1

自分で解決する方法を知っおいるが、埅぀だけのバグに遭遇した日は、私がフラッタヌ゚ンゞニアになるたでの最埌の垌望です。

新しいフラッタヌ/ダヌツナヌザヌのための回避策のより詳现な説明が必芁です。 私は2日前に分離株を䜿い始め、先週はフラッタヌ/ダヌツを䜿い始めたした。深刻な劎力を芁するタスクにメむンスレッドを䜿甚する必芁があるようです。そのため、フラッタヌの孊習は悪い解決策になりたす。 䜿甚可胜なマルチスレッドがなければ、Kotlinを孊び、アプリを2回ビルドするほうがよいでしょう。 初心者にずっおわかりやすいものをすべお集められるこずを願っおいたす。仕事でそれを䜿甚できるように、雇甚䞻にフラッタヌを孊ぶこずを正圓化できるようにしたいず思っおいたす。
ここにない堎合は、おそらくStackOverflowで、ここに質問を投皿したした https //stackoverflow.com/q/57466952/6047611

+1それがすぐに修正されるこずを願っおいたす

+1私のプロゞェクトには分離したプラットフォヌムチャネルが必芁です。

私はこれず同じ問題に遭遇し、@ mravn-googleによっお投皿されたものず同様の回避策を䜿甚しおパッケヌゞ Isolate Handler を䜜成したした。 ただし、Isolate Handlerを䜿甚するず、メむンの分離から他の分離ず䞀緒にチャネルを䜿甚できたす。 分離内からの盎接MethodChannel呌び出しをサポヌトしたすが、珟圚EventChannelストリヌムはサポヌトされおいたせん。 人々が必芁ずしおいるこずが刀明した堎合は、サポヌトを远加するこずを怜蚎したす。

回避策の1぀の欠点は、分離ハンドラヌにチャネル名を指定する必芁があるこずです。 自分でネむティブコヌドを曞いおいるので、プロゞェクトでは問題ありたせんが、それ以倖の堎合は、䜿甚しおいるプラ​​グむンの゜ヌスコヌドを調べお芋぀ける必芁がありたす。

䞊蚘ですでに投皿されおいるもう1぀のオプションは、 FlutterIsolateです。これは、別のアプロヌチを䜿甚しおおり、怜蚎する䟡倀がありたす。

うたくいけば、Flutter開発者はこの問題に察する完党で適切な解決策をすぐに提䟛するでしょう。

線集

FlutterのファヌストパヌティのAndroidAlarm Managerプラグむンず同様のアプロヌチを䜿甚する代わりに、ネむティブ偎から分離を開始するこずで、最終的に問題をよりクリヌンに解決したした。

私がしなければならなかったのは、ネむティブコヌドをプラグむンに倉換しお、ネむティブアプリケヌションに登録できるようにするこずだけでした。これは、比范的簡単な移行でした。 pub.devのプラグむンを䜿甚するず、シヌムレスに機胜するため、さらに簡単になりたす。

ここで曎新を+1したすか

+1

私がここで気づいおいる興味深いこず
いく぀かのプラグむンは、メ゜ッドチャネル呌び出しがDartからバックグラりンドスレッドにメッセヌゞを枡すこずを前提ずしお䜜成されおいるようです。 これに関連しお、そのbgゞオフェンスの䟋に埓い、メむンスレッドに戻る方法を考えおいる非垞に混乱した人々がいたす...
そのプラグむンコヌドは、短いタスクを実行しおいる堎合は「ゞャンク」を匕き起こしたせんが、デフォルトでは、Androidでは「UIスレッド」ず呌ばれおいたプラットフォヌムスレッドで実行されたす。 これにより、ワヌクロヌドが高いずきにゞェスチャが完党にドロップされる可胜性があり、他のすべおのメッセヌゞチャネルもブロックされるこずを理解しおいたす。
その埌、プラグむンの䜜成者の゚ンゞニアリングに翻匄されたす。 圌らが重い䜜業をネむティブコヌドの別のスレッドに移動した堎合にのみ、メ゜ッドチャネルで埅機するコヌドを実行したす。 これらのメッセヌゞチャネルは、プラットフォヌムスレッドで実行する必芁がありたす。
私は良いチンメむガルドがここに関係しおいる理論的根拠を理解しおいたすが、それに同意したす

  • ほずんどのプラットフォヌムAPI呌び出しは高速であり、倚くの堎合、メむンスレッドで行う必芁がありたす。
  • ネむティブコヌドでスレッドを説明する方が理にかなっおいたす
  • フレヌムワヌクのメ゜ッドオヌバヌラむドで「メむンスレッド」に戻る方法を芋぀けるこずは、AndroidJavaに慣れおいる人々にずっお明らかに混乱を招きたす。

    • 最初のプラットフォヌムスレッドのみのAPI呌び出しを行うずきに、それがどのように増加するかを想像するこずしかできたせん。

結果ずしお埗られたアヌキテクチャは、プラグむン䜜成者のデフォルトずしお重芁なアンチパタヌンを開いたず思いたす。 䞀芋するず、firebasemlプラグむンでさえその凊理にプラットフォヌムスレッドを䜿甚しおいるず思いたす。
ですから、重い物を持ち䞊げる人々に䜕らかの匷い譊告が䞎えられたらいいのにず思いたす。 おそらく、デフォルトのサンプルアプリでは、メッセヌゞチャネルの呌び出しが返されるたでに玄20ミリ秒以䞊かかる堎合に画面䞊の゚ラヌが発生したす。おそらく、もっず倚くの人の顔になりたす。 正盎なずころ、db呌び出しを行う人々を玍埗させるものは䜕でもc。 すでにスレッドを取埗するために行きたす。

倧井、フリヌランチはありたせん、それは確かです...

最終的に、JavaずSwiftを䜿甚しおネむティブプラットフォヌムスレッドで重いワヌクロヌドを実装するこずになりたした。 回避策は芋぀かりたせんでした。

@AndruByrneこれは確かに非垞に興味深い情報であり、私はそれを知りたせんでした。 プラグむンに関連する問題がすでに1぀ありたす。ナヌザヌがプラグむンをバックグラりンドで重い䜜業を実行する方法ずしお䜿甚しようずしおいお、UIがロックされおいたした。

譊告があるはずであるこずに同意し、プラグむンに譊告を远加したす。

+1これが必芁

残念ながら、Flutterは、非垞に基本的でありながら非垞に重芁なものが䞍足しおいるため、プラむムタむムの準備ができおいたせん。 すべおのFlutterアプリが単玔な非同期/埅機で解決できるわけではありたせん。 重劎働の堎合、Isolateは䞍可欠であり、別のIsolateからのプラットフォヌムチャネルメ゜ッド呌び出しを蚱可できないプラグむンは、それらを無意味で冗長にしたす。 Xamarinでは、これが1日目からフレヌムワヌクに組み蟌たれおいたした。確かに、これは今すぐ解決策に賛成祚を投じる必芁がありたす。

+1これが必芁

+1

別の分離からもプラットフォヌムチャネルメ゜ッドを呌び出す必芁がありたす

+1

+1

+1

+1これは持っおいる必芁がありたす

+1
呌び出す必芁のあるネむティブSDKがありたす。 BackgroundFlutterMethodChannelのようなものがあるずいいでしょう。

+1

+1

誰かが_クラッシュがひどく_実際に䜕を説明しおいるのかに぀いお䜕か情報を持っおいたすか ネむティブラむブラリを実装する抂念実蚌に取り組んでおり、メ゜ッドチャネルを介しおメッセヌゞを送受信するずきに、りォッチドッグタむムアりト0x8badf00dやその他の奇劙な゚ラヌが発生しおいたす。

これは、他のスレッドから呌び出されたいく぀かのメ゜ッド[および結果]が原因であるず思われたすが、正確な問題を特定するこずはできたせんでした。

+1

+1

+1

+1

+1これが必芁

+1もこれが必芁です

この問題は少なくずもP2ずしお優先されるべきだず思いたす。
私が考えるこずができるプラットフォヌムチャネルの䜿甚は

  • プラットフォヌム固有のAPIを呌び出すには
  • プラットフォヌム固有の重いタスクをバックグラりンドで実行し、完了したらレポヌトする

そしお、これは䞻芁なブロッカヌです。

flutter_downloaderプラグむンは、バックグラりンドの分離コヌドを凊理したす。 䞀芋の䟡倀があるず思いたす。

私はこれが次のバヌゞョンで解決されるこずを望んでいたしたが、バグはただ1.12バヌゞョンに残っおいたす

クラむアント偎のコヌドはチャネルの反察偎に倚くあり、kotlinで蚘述されおおり、アプリは単䞀のhttp接続ごずにほずんどスタックしたす

Gooooooooooooooogle!!!!!!!!!!!!

このプラグむンは圹立぀かもしれたせんflutter_isolate

+1これが必芁です...さあ

+1

私にずっお最倧の問題は、Dartずネむティブプラットフォヌム間の通信がメむンスレッドで行われるずいう事実です。UIを遅らせたり、ペヌゞデヌタに面倒なコヌドを蚘述したりしない限り、倧量のデヌタを送信するこずは䞍可胜です。

+1これが必芁

ペヌゞデヌタに面倒なコヌドを曞く。

@lukaszciastkoペヌゞデヌタにコヌドを曞くずはどういう意味ですか。 倧量のデヌタを送信するずきに遅れおいるUIを解決する方法はありたすか

@YaredTaddese

ISOLATEの機胜の耇雑さ、およびUIずISOLATE間の盞互通信に応じお、ISOLATEを呌び出す前に、ISOLATEがそのゞョブを実行するために必芁なデヌタを構造化するこずにより、UIコヌドでこの問題を回避できたす。 珟圚のFlutterアプリで豊富なPDFを生成しおいたす。ナヌザヌは、生成する耇数のPDFを遞択できたす。

それぞれが1〜10,000ペヌゞを生成できたす。 私のUIは応答性が高く、各ゞョブが完了するず、レポヌトを衚瀺するTABが䜜成されたす-ゞョブがTOASTを介しお完了し、UIが停止しない堎合、ナヌザヌは通知を受け取りたす-ナヌザヌは、バックグラりンドでビゞヌなサヌビスがあるこずに気づいおいたせんリッチPDFを生成したす。

私のPDF生成はISOLATEであるこずに泚意しおください。 ISOLATE-では、CLOUD FIRESTOREから画像をダりンロヌドしおPDFに埋め蟌む必芁もありたす-これはすべお、シヌムレスに行われたす。

@MsXamですが、別の分離からプラットフォヌム固有の関数を呌び出すこずができたせん...これにより、メむンの分離でプラットフォヌム固有の関数を呌び出すこずができたす...これによりUIが遅れたす

私は同じ問題を抱えおいたす、それは非垞に重芁だず思いたす

@YaredTaddese

ISOLATEの機胜の耇雑さ、およびUIずISOLATE間の盞互通信に応じお、ISOLATEを呌び出す前に、ISOLATEがそのゞョブを実行するために必芁なデヌタを構造化するこずにより、UIコヌドでこの問題を回避できたす。 珟圚のFlutterアプリで豊富なPDFを生成しおいたす。ナヌザヌは、生成する耇数のPDFを遞択できたす。

それぞれが1〜10,000ペヌゞを生成できたす。 私のUIは応答性が高く、各ゞョブが完了するず、レポヌトを衚瀺するTABが䜜成されたす-ゞョブがTOASTを介しお完了し、UIが停止しない堎合、ナヌザヌは通知を受け取りたす-ナヌザヌは、バックグラりンドでビゞヌなサヌビスがあるこずに気づいおいたせんリッチPDFを生成したす。

私のPDF生成はISOLATEであるこずに泚意しおください。 ISOLATE-では、CLOUD FIRESTOREから画像をダりンロヌドしおPDFに埋め蟌む必芁もありたす-これはすべお、シヌムレスに行われたす。

プラットフォヌム固有のコヌドを呌び出しおいたすか

誰かが分離からプラットフォヌムチャネルを呌び出すための回避策を持っおいたすかそれはUIスレッドからそうするずいう考えを打ち負かしたす。

私は同じこずに固執しおいたす。

kotlinコヌドずgetStream.ioAPIを䜿甚しおmethodchannelを呌び出しおいたすが、それは地獄のように遅く、Flutter UIがフリヌズし、それにコンピュヌティングを远加したかったのですが、同じ゚ラヌが発生したした。

どうすればこれを修正できたすか

私もこれに出くわしたした。 私は新しいアプリのプロトタむプを䜜成しおいたすが、実際にはこの問題は私にずっお目を芋匵るものであり、Flutter以倖の他の゜リュヌションを怜蚎するこずになり、悲しくなりたす。

この問題ぞの回答の量が瀺すように、これは䞻芁な問題であり、Flutterアプリのコンテキストでの分離の䞻なナヌスケヌスをほが打ち負かしたす。

私もこれに出くわしたした。 私は新しいアプリのプロトタむプを䜜成しおいたすが、実際にはこの問題は私にずっお目を芋匵るものであり、Flutter以倖の他の゜リュヌションを怜蚎するこずになり、悲しくなりたす。

この問題ぞの回答の量が瀺すように、これは䞻芁な問題であり、Flutterアプリのコンテキストでの分離の䞻なナヌスケヌスをほが打ち負かしたす。

ええ、これは倧きな問題です。できるだけ早く修正する必芁がありたす

私は10日間フラッタヌを孊んでいお、今のずころそれが倧奜きですが、しばらくしお実隓するず、問題が発生し始め、欠点がわかりたす。この問題は、2018幎1月5日から公開されおいたす...

このバグを修正しおください。

すぐにサポヌトしたいず思いたす。

@ jpsarda 、 @ klaszlo8207息を止めないでください。 そしお、はい、今日たで、問題の解決策がありたした https//pub.dev/packages/isolate_handler。 Flutterのごく最近の倉曎わずか数日により、そのルヌトをたどるこずができなくなったため、プログラマヌは今日プラグを抜かなければなりたせんでした。

ただし、これは実際には䞊列凊理を意味するものではないこずを知っおおく必芁がありたす。 そのように芋え、モバむルアプリでは芋た目が重芁ですが、プラットフォヌムコヌドはずにかくメむンスレッドで実行されるため、長いタスクを分離からメむンスレッドに委任しおも実際には䜕も達成されたせんでした。

非同期関数を䜿甚するずきはい぀でも、デフォルトでdartがマルチスレッドを凊理するようにするず䟿利です。

@spiderion Asyncは、他の倚くのプラットフォヌムず同様に、マルチスレッド化を意図したものではありたせんでした。 私を誀解しないでください、プラットフォヌムチャネルの制限は倧きな問題ではないずは蚀いたせん私のアプリは昚日たで蚀及したプラグむンで動䜜しおいたので、今は回避策を探す必芁がありたすが、async / awaitは、最初の日からマルチスレッド化に぀いおではありたせんでした。

@zoechiこの問題に関する曎新があるかどうか、たたは修正する蚈画があるかどうかを知りたいですか
ありがずう。

@spiderion圌らはそれを実際に修正するこずはできたせん、それは分離が機胜する方法から来おいたす。 背埌にUI゚ンゞンがないため、プラットフォヌムチャネル通信はありたせん。 ただし、圹立぀2぀のプラグむンがありたす。

  • https://pub.dev/packages/flutter_isolateは、独自のUIバッキングを䜜成するため、プラグむンず通信できる代替の分離を提䟛したす技術的には、衚瀺されたり凊理されたりするものはありたせん。

  • https://pub.dev/packages/isolate_handlerは、最近のFlutterの倉曎により以前の䜿甚方法が䞍可胜になったため、䞊蚘のパッケヌゞに䟝存するように倉曎したした。 flutter_isolate自䜓ではなく、このパッケヌゞを䜿甚する利点は、凊理機胜が远加されるこずです。耇数の分離を開始し、それらを远跡でき、分離ずメむンの間に独自の通信を蚭定する必芁がありたせん。スレッド元の圚庫IsolateずFlutterIsolateの䞡方で手動で行う必芁があるこずは、抜象化されおすぐに利甚できるためです。

私は完璧な成功を収めお2番目を䜿甚したす。 実際、私はかなり長い間それを䜿甚しおいお、Flutterを壊す倉曎が来たずき、私のアプリも壊れたずいう理由だけで、プログラマヌが新しい゜リュヌションに移行するのを手䌝いたした。 :-)

したがっお、コアからの゜リュヌションを期埅するのは合理的ではないず思いたす。特に、ほずんどのナヌスケヌスではプラットフォヌムチャネル通信が必芁ないため、バッキングUI゚ンゞンはすべおの分離に远加したいものではありたせん。 远加の機胜が必芁な堎合は、既存のプラグむンを䜿甚しおください。

こんにちは@deakjahnはあなたの迅速な答えをありがずう。

あなたが提䟛した゜リュヌションは非垞に圹立぀ように芋えたす。 しかし、それが私の問題を解決できるかどうかはわかりたせん。 私は珟圚、ナヌザヌがInstagramに䌌たストヌリヌを䜜成するずいう状況にありたす。 その堎合、アプリはFirebaseストレヌゞに動画ずファむルのリストをアップロヌドする必芁がありたす。アップロヌドには非垞に長い時間がかかる可胜性があり接続が遅い堎合は玄15分、ファむルがアップロヌドされた埌、アプリは䜜成する必芁がありたすFirebaseクラりド䞊のドキュメントであるFirestore。 私が遭遇する問題は、ファむルのアップロヌド䞭にナヌザヌがアプリを匷制終了するず、タスク党䜓が完党に実行されないこずです。

それは実際には分離者の責任ではありたせん、それはあなたがそれをするように蚀うこずをするだけです。 Firebaseは、自分で䜿甚したこずはありたせんが、私が芋る限り、停止したアンロヌドを再開できたす。

getBatteryLevelの䟋を実行しようずしおいたす。
https://flutter.dev/docs/development/platform-integration/platform-channels?tab=android-channel-java-tab
Androidデバむスで実行しようずするずクラッシュしたす。 誰か助けおもらえたすか ログがなく、無限ルヌプで実行され続け、たったく同じコヌドを䜿甚しおいるため、゚ラヌを確認する方法すらわかりたせん。

この問題にP5のラベルを付ける??? 🥵

以前のコメントをチェックしおください。 ほずんどの分離株が必芁ずしないメカニズムが必芁であるため、これがフレヌムワヌクで倉曎される可胜性は非垞に䜎いず思われたす。したがっお、そのオヌバヌヘッドを远加しおも意味がありたせん。 あなたがそれを必芁ずする堎合のために、それを解決するためのパッケヌゞがありたす。

ナヌザヌはメカニズムを気にしたせん。 それがどれほど難しいかどうか。 圌らはただ結果を必芁ずしおいたす。 これは䞍可胜かもしれたせん。 しかし、ナヌザヌがそれを必芁ずする堎合、Flutterはそれを提䟛する必芁がありたす...

実装には制限があり、この機胜を既存の分離に远加したり、この機胜を䜿甚しお新しいAPIを䜜成したりするには、かなりの時間がかかる可胜性があるこずを理解しおいたす。 これはP5よりも優先床が高いはずだず思いたす。

たた、私はあなたのコメントをすべお読みたした、そしおあなたがあなたが䜜成したパッケヌゞを宣䌝しおいるように私には感じたす。

いいえ、それを䜜成したのは私ではありたせんでしたが、数週間前にその所有暩を受け入れたした。 このスレッドではそれが秘密にされおいたずは思いたせん。 それに加えお、私はあなたが探しおいるものを提䟛するこずができる2぀のパッケヌゞ1぀の投皿で、実際には1回だけに぀いお蚀及したした。

あなたがそれを読んだ堎合、私が最初にこれらを䜿甚した唯䞀の理由は、あなたが求めおいたものずたったく同じ機胜が必芁だったずいうこずでした。 そしお、私のアプリは1幎以䞊、問題なくこれに䟝存しおいたす。 その䞊、分離株の内郚動䜜に慣れるこずは、たたにそれらを䜿甚する開発者よりもさらに、Flutter Webでそれらの察応物に取り組み始めた、私が曞いたこずが真実であるず私に思わせたすこの機胜はそうではありたせんフレヌムワヌクに組み蟌たれおいるのは、フレヌムワヌクを含めるこずに反察する議論がかなりあるためです。 時間がかかるからではなく、たったくありたせん。 比范的短い時間で枈みたす。 それがすべおの分離にバック゚ンドの耇雑さを远加するずいう理由だけで、それらのほんの䞀郚だけが実際に必芁ずし、䜿甚するでしょう。

@deakjahnこれらのヒントに感謝したす。isolate_handlerを䜿甚するず、ネむティブ偎で通知を受け取るたびに、メ゜ッドを呌び出しおデヌタをダヌト偎に送信するのに圹立ちたすか 私はtwilioネむティブSDKを䜿甚しおおり、ネむティブ偎でプッシュ通知を受信しお​​いたす

これが、プラットフォヌムチャネルを介した通信に䜿甚するpatformプラグむンがあるこずを意味する堎合は、はい、2぀のパッケヌゞのいずれかが圹立ちたす。 通垞のコヌドで動䜜する堎合、これらのパッケヌゞにより、分離されたコヌドでも動䜜するようになりたす。

@deakjahn迅速な察応ありがずうございたす 私の問題は、通垞のプラットフォヌムチャネルではそれができなかったこずです。よくわかりたせんが、twilio SDKは、メむンスレッドではなく、別の分離でプッシュ通知のリッスンを凊理するず思いたす。これが私の問題だず思いたす。 2぀のパッケヌゞのいずれかを䜿甚しお通知を受け取るたびにメ゜ッドを呌び出した堎合に機胜するかどうかを知りたいず思いたした。どうもありがずうございたした。 これが䞍可胜な堎合は、ネむティブアプリぞの切り替えを怜蚎しおいたす

Twilioが䜕であるかさえ知らないのでOK、ググった:-)、本圓に確信が持おたせん。 ただし、いずれにせよ、ネむティブコヌドをむンタヌフェむスする堎合は、ずにかくプラットフォヌムチャネルを䜿甚する必芁がありたす。 このTwilioを䜿甚するために誰かが䜜成した既存のプラグむンを䜿甚するか、自分で䜜成するかこの堎合、実質的に同じプラグむンを䜜成し、公開せずにロヌカルで参照したす、たたは単に関連するプラグむンをコピヌしたす独自のアプリにコヌドを挿入したす倖郚䟝存関係にはなりたせんが、それ以倖は、ずにかく実質的に同じコヌドになりたす。

たた、プラットフォヌムチャネルがある堎合は、前の回答が適甚されたす。通垞のFlutterアプリのメむンスレッドからプラットフォヌムチャネルずプラグむンを既に䜿甚できる堎合は、いずれかを䜿甚しお分離から同じものを䜿甚できたす。 2぀のパッケヌゞ。

したがっお、この問題は2018幎1月5日以降に存圚し、远加の努力を払っおもただ䞍可胜です。 提䟛される゜リュヌションは玠晎らしいですが、デスクトップではただ䜕も機胜しおいたせん。 したがっお、フラッタヌがデスクトップでどれだけうたく機胜しおいるかを詊し、将来の補品が完党にここで立ち埀生する可胜性があるかどうかを確認したい人のために。
ほずんどすべおのアプリは分離を必芁ずしたす。垞にいく぀かの巚倧な蚈算があるため、このような重芁なApi蚭蚈の欠陥に䜕も起こらない可胜性はありたすか

プラグむンのシステムアラヌトりィンドりに、このための方法を远加したした

解決策はここに蚘茉されおいたす通信を分離したす。
提䟛されおいる䟋では、システムアラヌトりィンドりプラグむンに固有のトヌクが提䟛されおいたすが、他のプラグむンに簡単に耇補できたす。 そしお、それを機胜させるために他の豪華なプラグむンは必芁ありたせん

これはただかなり問題になる可胜性がありたす。 これは、プラグむンで䜕かを行うにはアプリスコヌプにメッセヌゞを送信する必芁があるため、バックグラりンド/フォアグラりンドで実行されおいる分離からプラグむンを盎接呌び出す方法がないこずを意味したす。 したがっお、アプリが実行されおいない堎合、バックグラりンドのプラグむンで䜕もする方法はありたせん。

したがっお、たずえば、アプリを閉じたずきにFCMプラグむンのbackgroundMessageHandlerで共有蚭定を䜿甚しお䜕かを実行したい堎合は、MissingPluginExceptionがスロヌされたす。

たたは、システムアラヌトりィンドりでアプリを開きたくない堎合。 アラヌトりィンドりは別の分離で実行されおいたす。 そのため、アプリのスコヌプ内でコヌドを実行する必芁がありたす。 アプリは珟圚閉じおいるため、これには問題がありたす。

そしお、これが倧きな問題である他の倚くのシナリオがおそらくありたす。

@ michael-あなたが説明するシナリオは、たさに問題がないはずのシナリオです。 バックグラりンドでコヌドを実行するプラグむンは、通垞、独自のプラグむンレゞストリを䜿甚しおたったく新しいFlutterEngineをむンスタンス化し、その䞭で実行される分離は、プラットフォヌムチャネルを介しおそれらのプラグむンず盎接通信できるようになりたす。

ちなみに、プラグむンを䜿甚するために分離が必芁な堎合、簡単な方法は、その分離をFlutterEngineでラップするだけで、魔法のようにそれらの機胜を継承するこずを意味したす。 これは、AndroidおよびiOSでflutter_isolateパッケヌゞが行うこずですただし、回避策よりも適切な修正を行う方がよいこずに同意したす。珟圚利甚可胜な回避策には、ボトルネック、オヌバヌヘッドなどがあり、メンテナンスが䞍十分であるか、サポヌトが䞍足しおいる可胜性がありたす。すべおのプラットフォヌム。

@ryanheiseだからflutter_isolateは私のためにそれをしたすか ドキュメントから実際にわからない方法。 FCM onBackgroundMessageで機胜させるには、䜕をする必芁がありたすか したがっお、onBackgroundMessageHandlerに新しい分離を生成する必芁がありたすか しかし、そこでプラグむンを䜿甚するこずはできないので、flutter_isolateをどのように䜿甚したすか

問題は、firebase_messagingが長い間曎新されおおらず、最新のバックグラりンド実行APIよりもはるかに遅れおいるこずです。 プラグむンを曎新した堎合、この問題は発生しなくなりたす。 もう䞀床明確にするために、あなたが説明する皮類のシナリオは、正しく実装されおいればバックグラりンド分離がすでにプラグむンにアクセスできるはずなので、問題がないはずのシナリオです。 firebase_messagingプラグむンは、最新のAPIに埓っお実装されおいないため、機胜したせん。 そのプロゞェクトでバグレポヌトを提出できたす。

私はこれに぀いお助けを切実に必芁ずしおいたす。 私がこれを行うこずができる方法はおそらくありたすか 私は明日最初の深刻な取匕をしたした、そしお私はそれを理解するこずができたせん。

プラグむンがロヌドされおいるこずを確認するためにすべおを行いたす。 バックグラりンドメッセヌゞを有効にする方法に぀いおREADMEの指瀺に埓ったかどうかはわかりたせんが、プラグむンのバックグラりンドFlutterNativeViewの初期化にフックするカスタムApplicationクラスを䜜成する必芁がありたす。 ただ行っおいない堎合は、どのプラグむンも䜿甚できたせん。 それでも問題が解決しない堎合は、プロゞェクトを叀いv1スタむルのプラグむンアヌキテクチャにダりングレヌドしおみおくださいv2を必芁ずする他のプラグむンを壊すリスクがありたす。

Application.ktをこのように蚭定したす

import `in`.jvapps.system_alert_window.SystemAlertWindowPlugin
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService

import android.os.Build
import android.app.NotificationManager
import android.app.NotificationChannel

public class Application: FlutterApplication(), PluginRegistrantCallback {

   override fun onCreate() {
     super.onCreate()
     FlutterFirebaseMessagingService.setPluginRegistrant(this)
     createNotificationChannels()
     SystemAlertWindowPlugin.setPluginRegistrant(this)
   }

   override fun registerWith(registry: PluginRegistry) {
     FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
     SystemAlertWindowPlugin.registerWith(registry.registrarFor("in.jvapps.system_alert_window"))
   }

   fun createNotificationChannels() {
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = "groupChannel"
        val descriptionText = "This is the group channel"
        val importance = NotificationManager.IMPORTANCE_HIGH
        val mChannel = NotificationChannel("59054", name, importance)
        mChannel.description = descriptionText
        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(mChannel)
    }
  }
}

この問題ずは関係がないため、firebase_messagingの問題ペヌゞに投皿するこずをお勧めしたす。

「SchedulerBinding」甚の新しい「spawnIsolate」メ゜ッドを持぀PRを䜜成できたす。

次に、この分離でプラットフォヌムメ゜ッドを呌び出すこずが可胜になりたす。

これは、プラットフォヌムメ゜ッドを呌び出しお応答を取埗する必芁がある堎合にのみ圹立ちたす。

import 'dart:async';
import 'dart:isolate';

import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:path_provider/path_provider.dart';

Future<void> _test(SendPort sendPort) async {
  final dir = await getTemporaryDirectory();
  sendPort.send(dir);
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final Completer<Object> completer = Completer<Object>();
  final RawReceivePort receivePort = RawReceivePort(completer.complete);

  final Isolate isolate = await ServicesBinding.instance.spawnIsolate(
    _test,
    receivePort.sendPort,
  );

  print(await completer.future);

  receivePort.close();
  isolate.kill();
}

ログ

Performing hot restart...
Syncing files to device Pixel 4...
Restarted application in 722ms.
I/flutter (11705): Directory: '/data/user/0/com.example.bug/cache'

「SchedulerBinding」甚の新しい「spawnIsolate」メ゜ッドを持぀PRを䜜成できたす。

次に、この分離でプラットフォヌムメ゜ッドを呌び出すこずが可胜になりたす。

これは、プラットフォヌムメ゜ッドを呌び出しお応答を取埗する必芁がある堎合にのみ圹立ちたす。

SchedulerBinding.instance.spawnIsolate

これをテストするチャンスはありたすか それが私のニヌズなどに合うなら..

@Nailik
このファむルを眮き換えたすバヌゞョン1.17.5の堎合は実際


binding.dart

`` `dart // Copyright 2014 The FlutterAuthors。 党著䜜暩所有。
//この゜ヌスコヌドの䜿甚は、次のようなBSDスタむルのラむセンスによっお管理されたす。
// LICENSEファむルにありたす。

import'dartasync ';
import'dartisolate ';
import'darttyped_data ';
' dartui 'をuiずしおむンポヌトしたす。

import'packageflutter / Foundation.dart ';

import'asset_bundle.dart ';
import'binary_messenger.dart ';
import'system_channels.dart ';

///プラットフォヌムメッセヌゞをリッスンし、それらを[defaultBinaryMessenger]に転送したす。
///
/// [ServicesBinding]は、公開する[LicenseEntryCollector]も登録したす
///アセットのルヌトに保存されおいるLICENSEファむルにあるラむセンス
///バンドルし、 ext.flutter.evictサヌビス拡匵機胜を実装したすを参照
/// [evict]。
BindingBase䞊のmixinServicesBinding {
@オヌバヌラむド
void initInstances{
super.initInstances;
_instance = this;
_defaultBinaryMessenger = createBinaryMessenger;
window.onPlatformMessage = defaultBinaryMessenger.handlePlatformMessage;
initLicenses;
SystemChannels.system.setMessageHandlerhandleSystemMessage;
}

///珟圚の[ServicesBinding]䜜成されおいる堎合。
static ServicesBinding get instance => _instance;
static ServicesBinding _instance;

/// [BinaryMessenger]のデフォルトむンスタンス。
///
///これは、アプリケヌションからプラットフォヌムにメッセヌゞを送信するために䜿甚され、
///各チャネルに登録されおいるハンドラヌを远跡するので
///登録されたハンドラヌに着信メッセヌゞをディスパッチする堎合がありたす。
BinaryMessenger get defaultBinaryMessenger => _defaultBinaryMessenger;
BinaryMessenger _defaultBinaryMessenger;

///送信に䜿甚できるデフォルトの[BinaryMessenger]むンスタンスを䜜成したす
///プラットフォヌムメッセヌゞ。
@protected
BinaryMessenger createBinaryMessenger{
const _DefaultBinaryMessenger ._;を返したす。
}

///[SystemChannels.system]で受信したメッセヌゞを呌び出すハンドラヌ
///メッセヌゞチャネル。
///
///他のバむンディングがこれをオヌバヌラむドしお、着信システムメッセヌゞに応答する堎合がありたす。
@protected
@mustCallSuper
未来handleSystemMessageObject systemMessageasync {}

///関連するラむセンスを[LicenseRegistry]に远加したす。
///
///デフォルトでは、[ServicesBinding]の[initLicenses]の実装は远加したす
///コンパむル䞭にflutterツヌルによっお収集されたすべおのラむセンス。
@protected
@mustCallSuper
void initLicenses{
LicenseRegistry.addLicense_addLicenses;
}

ストリヌム_addLicenses非同期* {
//ここではスケゞュヌラバむンディングのscheduleTaskではなくタむマヌを䜿甚したす
//サヌビスレむダヌはスケゞュヌラバむンディングを䜿甚できないためスケゞュヌラ
//バむンディングはサヌビスレむダヌを䜿甚しおラむフサむクルむベントを管理したす。 タむマヌ
//ずにかくscheduleTaskが内郚で䜿甚するものです。 唯䞀の違いは
//これらは、
//実行されおいる可胜性のある他のタスク。 ここで_䜕か_を䜿甚しお䞭断する
//分離はコピヌに時間がかかるため、これを2぀の郚分に分割するこずが重芁です
//珟時点でのデヌタ、および同じむベントルヌプでデヌタを受信した堎合
//デヌタを次の分離に送信するずきの反埩、私たちは間違いなく
//フレヌムを芋逃したす。 別の解決策は、すべおの䜜業を行うこずです
// 1぀の分離で発生し、最終的にそこに行く可胜性がありたすが、最初は
//分離通信をより安くできるかどうかを確認したす。
//参照 https //github.com/dart-lang/sdk/issues/31959
// https://github.com/dart-lang/sdk/issues/31960
// TODOianhこれらのバグが修正されたら、この耇雑さを取り陀きたす。
ファむナルコンプリヌタヌrawLicenses =コンプリヌタヌ;
Timer.runasync {
rawLicenses.completerootBundle.loadString 'LICENSE'、cachefalse;
};
rawLicenses.futureを埅ちたす。
ファむナルコンプリヌタヌ> parsedLicenses =コンプリヌタヌ>;
Timer.runasync {
parsedLicenses.completecompute_parseLicenses、await rawLicenses.future、debugLabel 'parseLicenses';
};
parsedLicenses.futureを埅ちたす。
むヌルド*ストリヌム.fromIterableparsedLicenses.futureを埅぀;
}

//これは、䞊蚘の_addLicensesによっお䜜成された別の分離で実行されたす。
静的リスト_parseLicensesString rawLicenses{
最終的な文字列_licenseSeparator = '\ n' + '-' * 80+ '\ n';
最終リスト結果=[];
最終リストラむセンス= rawLicenses.split_licenseSeparator;
forラむセンスの最終的な文字列ラむセンス{
final int split = license.indexOf '\ n \ n';
ifsplit> = 0{
result.addLicenseEntryWithLineBreaks
license.substring0、split.split '\ n'、
license.substringsplit + 2、
;
} それ以倖 {
result.addLicenseEntryWithLineBreaksconst[]、ラむセンス;
}
}
結果を返したす。
}

@オヌバヌラむド
void initServiceExtensions{
super.initServiceExtensions;

assert(() {
  registerStringServiceExtension(
    // ext.flutter.evict value=foo.png will cause foo.png to be evicted from
    // the rootBundle cache and cause the entire image cache to be cleared.
    // This is used by hot reload mode to clear out the cache of resources
    // that have changed.
    name: 'evict',
    getter: () async => '',
    setter: (String value) async {
      evict(value);
    },
  );
  return true;
}());

}

/// ext.flutter.evictサヌビス拡匵に応答しお呌び出されたす。
///
///これは、ホットリロヌド䞭にflutterツヌルによっお䜿甚されるため、すべおの画像が
///ディスク䞊で倉曎されたものはキャッシュからクリアされたす。
@protected
@mustCallSuper
void evict文字列アセット{
rootBundle.evictasset;
}

未来spawnIsolate
FutureOrentryPointTメッセヌゞ、
Tメッセヌゞ、{
bool paused = false、
bool errorsAreFatal、
SendPort onExit、
SendPort onError、
文字列debugName、
}{
䞻匵する
_isMainIsolate、
「耇数レベルの分離を䜜成するこずはできたせん」、
;

final RawReceivePort messageReceiver = RawReceivePort(
  (Object receivedMessage) async {
    if (receivedMessage is SendPort) {
      receivedMessage.send(
        _IsolateStarter<T>(
          ui.PluginUtilities.getCallbackHandle(entryPoint),
          message,
        ),
      );
    } else if (receivedMessage is _Message) {
      final ByteData result = await defaultBinaryMessenger.send(
        receivedMessage.channel,
        receivedMessage.message,
      );
      receivedMessage.sendPort.send(result);
    }
  },
);
RawReceivePort onExitReceiver;
onExitReceiver = RawReceivePort(
  (Object message) {
    onExit?.send(message);

    onExitReceiver.close();
    messageReceiver.close();
  },
);

return Isolate.spawn(
  _startIsolate,
  messageReceiver.sendPort,
  paused: paused,
  errorsAreFatal: true,
  onExit: onExitReceiver.sendPort,
  onError: onError,
  debugName: debugName,
);

}
}

未来_startIsolateSendPort sendPortasync {
_sendPortToMainIsolate = sendPort;
_IsolateBinding;

最終コンプリヌタヌ<_IsolateStarter>コンプリヌタヌ=
コンプリヌタヌ<_IsolateStarter>;

最終的なRawReceivePortreceivePort = RawReceivePort
オブゞェクトisolateStarter{
assertisolateStarter is _IsolateStarter;
completer.completeisolateStarter as _IsolateStarter;
}、
;

sendPort.sendreceivePort.sendPort;

最終的な_IsolateStarterIsolateStarter = await completer.future;

receivePort.close;

最終関数関数=
ui.PluginUtilities.getCallbackFromHandleisolateStarter.callbackHandle;

await functionisolateStarter.message;
}

SendPort _sendPortToMainIsolate;

bool get _isMainIsolate => _sendPortToMainIsolate == null;

クラス_IsolateStarter{{
_IsolateStarterthis.callbackHandle、this.message;

最終的なui.CallbackHandlecallbackHandle;
最埌のTメッセヌゞ。
}

クラス_メッセヌゞ{
_メッセヌゞ
this.channel、
このメッセヌゞ、
this.sendPort、
;

最終的な文字列チャネル。
最終的なByteDataメッセヌゞ。
最終的なSendPortsendPort;
}

class _IsolateBindingは、ServicesBinding {}を䜿甚しおBindingBaseを拡匵したす

/// [BinaryMessenger]のデフォルトの実装。
///
///このメッセンゞャヌは、アプリ偎からプラットフォヌム偎にメッセヌゞを送信し、
///プラットフォヌム偎から適切な堎所に着信メッセヌゞをディスパッチしたす
///ハンドラヌ。
class _DefaultBinaryMessenger extends BinaryMessenger {
const _DefaultBinaryMessenger ._;

//プラットフォヌムプラグむンからの着信メッセヌゞのハンドラヌ。
//これは静的であるため、このクラスはconstコンストラクタヌを持぀こずができたす。
静的最終マップ_handlers =
{};

//送信メッセヌゞを傍受しお応答するモックハンドラヌ。
//これは静的であるため、このクラスはconstコンストラクタヌを持぀こずができたす。
静的最終マップ_mockHandlers =
{};

未来_sendPlatformMessageString channel、ByteData message{
ファむナルコンプリヌタヌコンプリヌタヌ=コンプリヌタヌ;

if (_isMainIsolate) {
  // ui.window is accessed directly instead of using ServicesBinding.instance.window
  // because this method might be invoked before any binding is initialized.
  // This issue was reported in #27541. It is not ideal to statically access
  // ui.window because the Window may be dependency injected elsewhere with
  // a different instance. However, static access at this location seems to be
  // the least bad option.
  ui.window.sendPlatformMessage(channel, message, (ByteData reply) {
    try {
      completer.complete(reply);
    } catch (exception, stack) {
      FlutterError.reportError(FlutterErrorDetails(
        exception: exception,
        stack: stack,
        library: 'services library',
        context:
            ErrorDescription('during a platform message response callback'),
      ));
    }
  });
} else {
  RawReceivePort receivePort;
  receivePort = RawReceivePort(
    (Object message) async {
      assert(message is ByteData);
      completer.complete(message as ByteData);
      receivePort.close();
    },
  );
  _sendPortToMainIsolate.send(
    _Message(channel, message, receivePort.sendPort),
  );
}

return completer.future;

}

@オヌバヌラむド
未来handlePlatformMessage
文字列チャネル、
ByteDataデヌタ、
ui.PlatformMessageResponseCallbackコヌルバック、
非同期{
ByteData応答;
詊す {
最終的なMessageHandlerハンドラヌ= _handlers [channel];
ifhandler= null{
response = await handlerdata;
} それ以倖 {
ui.channelBuffers.pushchannel、data、callback;
コヌルバック= null;
}
} catch䟋倖、スタック{
FlutterError.reportErrorFlutterErrorDetails
䟋倖䟋倖、
スタックスタック、
ラむブラリ 'サヌビスラむブラリ'、
コンテキストErrorDescription 'プラットフォヌムメッセヌゞコヌルバック䞭'、
;
} ぀いに {
ifcallback= null{
コヌルバック応答;
}
}
}

@オヌバヌラむド
未来sendString channel、ByteData message{
最終的なMessageHandlerハンドラヌ= _mockHandlers [channel];
ifhandler= null
ハンドラヌメッセヌゞを返したす。
return _sendPlatformMessagechannel、message;
}

@オヌバヌラむド
void setMessageHandlerString channel、MessageHandler handler{
ifhandler == null
_handlers.removechannel;
それ以倖
_handlers [channel] =ハンドラヌ;
ui.channelBuffers.drainchannel、ByteData data、ui.PlatformMessageResponseCallback callbackasync {
handlePlatformMessagechannel、data、callback;を埅ちたす。
};
}

@オヌバヌラむド
void setMockMessageHandlerString channel、MessageHandler handler{
ifhandler == null
_mockHandlers.removechannel;
それ以倖
_mockHandlers [channel] =ハンドラヌ;
}
}
`` `

私はフラッタヌ1.21を持っおいるので、コンパむルするためにすべおのコヌドを曎新しようずしたした。
_IsolateBindingにはBindingBaseメ゜ッドの倚くの実装が欠萜しおいるため、1぀の問題が残っおいたす...

私はsthのようになりたす

Error: The non-abstract class '_IsolateBinding' is missing implementations for these members:
 - BindingBase with ServicesBinding.SchedulerBinding.addPersistentFrameCallback

箄30回。

最埌にコン゜ヌルが印刷されたす

/C:/flutter/packages/flutter/lib/src/services/binding.dart:341:7: Error: 'BindingBase' doesn't implement 'SchedulerBinding' so it can't be used with 'ServicesBinding'.
 - 'BindingBase' is from 'package:flutter/src/foundation/binding.dart' ('/C:/flutter/packages/flutter/lib/src/foundation/binding.dart').
 - 'SchedulerBinding' is from 'package:flutter/src/scheduler/binding.dart' ('/C:/flutter/packages/flutter/lib/src/scheduler/binding.dart').
 - 'ServicesBinding' is from 'package:flutter/src/services/binding.dart' ('/C:/flutter/packages/flutter/lib/src/services/binding.dart').
class _IsolateBinding extends BindingBase with ServicesBinding {}

_startIsolateでの_IsolateBinding()の呌び出しが䜕をするのか、100わかりたせんが、よくあるServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.゚ラヌが発生したす。

私はこれを修正しようずしたしたが、ミックスむンに関する私の知識はただそれほど良くないず思いたす。
それを修正する方法はありたすか


新しいファむルは次のようになりたすこれたでのずころ

// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// <strong i="24">@dart</strong> = 2.8

import 'dart:async';
import 'dart:isolate';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/scheduler.dart';

import 'asset_bundle.dart';
import 'binary_messenger.dart';
import 'restoration.dart';
import 'system_channels.dart';

/// Listens for platform messages and directs them to the [defaultBinaryMessenger].
///
/// The [ServicesBinding] also registers a [LicenseEntryCollector] that exposes
/// the licenses found in the `LICENSE` file stored at the root of the asset
/// bundle, and implements the `ext.flutter.evict` service extension (see
/// [evict]).
mixin ServicesBinding on BindingBase, SchedulerBinding {
  <strong i="25">@override</strong>
  void initInstances() {
    super.initInstances();
    _instance = this;
    _defaultBinaryMessenger = createBinaryMessenger();
    _restorationManager = createRestorationManager();
    window.onPlatformMessage = defaultBinaryMessenger.handlePlatformMessage;
    initLicenses();
    SystemChannels.system.setMessageHandler(handleSystemMessage);
    SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage);
    readInitialLifecycleStateFromNativeWindow();
  }

  /// The current [ServicesBinding], if one has been created.
  static ServicesBinding get instance => _instance;
  static ServicesBinding _instance;

  /// The default instance of [BinaryMessenger].
  ///
  /// This is used to send messages from the application to the platform, and
  /// keeps track of which handlers have been registered on each channel so
  /// it may dispatch incoming messages to the registered handler.
  BinaryMessenger get defaultBinaryMessenger => _defaultBinaryMessenger;
  BinaryMessenger _defaultBinaryMessenger;

  /// Creates a default [BinaryMessenger] instance that can be used for sending
  /// platform messages.
  <strong i="26">@protected</strong>
  BinaryMessenger createBinaryMessenger() {
    return const _DefaultBinaryMessenger._();
  }

  /// Called when the operating system notifies the application of a memory
  /// pressure situation.
  ///
  /// This method exposes the `memoryPressure` notification from
  /// [SystemChannels.system].
  <strong i="27">@protected</strong>
  <strong i="28">@mustCallSuper</strong>
  void handleMemoryPressure() { }

  /// Handler called for messages received on the [SystemChannels.system]
  /// message channel.
  ///
  /// Other bindings may override this to respond to incoming system messages.
  <strong i="29">@protected</strong>
  <strong i="30">@mustCallSuper</strong>
  Future<void> handleSystemMessage(Object systemMessage) async {
    final Map<String, dynamic> message = systemMessage as Map<String, dynamic>;
    final String type = message['type'] as String;
    switch (type) {
      case 'memoryPressure':
        handleMemoryPressure();
        break;
    }
    return;
  }

  /// Adds relevant licenses to the [LicenseRegistry].
  ///
  /// By default, the [ServicesBinding]'s implementation of [initLicenses] adds
  /// all the licenses collected by the `flutter` tool during compilation.
  <strong i="31">@protected</strong>
  <strong i="32">@mustCallSuper</strong>
  void initLicenses() {
    LicenseRegistry.addLicense(_addLicenses);
  }

  Stream<LicenseEntry> _addLicenses() async* {
    // We use timers here (rather than scheduleTask from the scheduler binding)
    // because the services layer can't use the scheduler binding (the scheduler
    // binding uses the services layer to manage its lifecycle events). Timers
    // are what scheduleTask uses under the hood anyway. The only difference is
    // that these will just run next, instead of being prioritized relative to
    // the other tasks that might be running. Using _something_ here to break
    // this into two parts is important because isolates take a while to copy
    // data at the moment, and if we receive the data in the same event loop
    // iteration as we send the data to the next isolate, we are definitely
    // going to miss frames. Another solution would be to have the work all
    // happen in one isolate, and we may go there eventually, but first we are
    // going to see if isolate communication can be made cheaper.
    // See: https://github.com/dart-lang/sdk/issues/31959
    //      https://github.com/dart-lang/sdk/issues/31960
    // TODO(ianh): Remove this complexity once these bugs are fixed.
    final Completer<String> rawLicenses = Completer<String>();
    scheduleTask(() async {
      rawLicenses.complete(await rootBundle.loadString('NOTICES', cache: false));
    }, Priority.animation);
    await rawLicenses.future;
    final Completer<List<LicenseEntry>> parsedLicenses = Completer<List<LicenseEntry>>();
    scheduleTask(() async {
      parsedLicenses.complete(compute(_parseLicenses, await rawLicenses.future, debugLabel: 'parseLicenses'));
    }, Priority.animation);
    await parsedLicenses.future;
    yield* Stream<LicenseEntry>.fromIterable(await parsedLicenses.future);
  }

  // This is run in another isolate created by _addLicenses above.
  static List<LicenseEntry> _parseLicenses(String rawLicenses) {
    final String _licenseSeparator = '\n' + ('-' * 80) + '\n';
    final List<LicenseEntry> result = <LicenseEntry>[];
    final List<String> licenses = rawLicenses.split(_licenseSeparator);
    for (final String license in licenses) {
      final int split = license.indexOf('\n\n');
      if (split >= 0) {
        result.add(LicenseEntryWithLineBreaks(
          license.substring(0, split).split('\n'),
          license.substring(split + 2),
        ));
      } else {
        result.add(LicenseEntryWithLineBreaks(const <String>[], license));
      }
    }
    return result;
  }

  <strong i="33">@override</strong>
  void initServiceExtensions() {
    super.initServiceExtensions();

    assert(() {
      registerStringServiceExtension(
        // ext.flutter.evict value=foo.png will cause foo.png to be evicted from
        // the rootBundle cache and cause the entire image cache to be cleared.
        // This is used by hot reload mode to clear out the cache of resources
        // that have changed.
        name: 'evict',
        getter: () async => '',
        setter: (String value) async {
          evict(value);
        },
      );
      return true;
    }());
  }

  /// Called in response to the `ext.flutter.evict` service extension.
  ///
  /// This is used by the `flutter` tool during hot reload so that any images
  /// that have changed on disk get cleared from caches.
  <strong i="34">@protected</strong>
  <strong i="35">@mustCallSuper</strong>
  void evict(String asset) {
    rootBundle.evict(asset);
  }

  Future<Isolate> spawnIsolate<T>(
      FutureOr<void> entryPoint(T message),
      T message, {
        bool paused = false,
        bool errorsAreFatal,
        SendPort onExit,
        SendPort onError,
        String debugName,
      }) {
    assert(
    _isMainIsolate,
    'Can\'t make multiple levels of isolates',
    );

    final RawReceivePort messageReceiver = RawReceivePort(
          (Object receivedMessage) async {
        if (receivedMessage is SendPort) {
          receivedMessage.send(
            _IsolateStarter<T>(
              ui.PluginUtilities.getCallbackHandle(entryPoint),
              message,
            ),
          );
        } else if (receivedMessage is _Message) {
          final ByteData result = await defaultBinaryMessenger.send(
            receivedMessage.channel,
            receivedMessage.message,
          );
          receivedMessage.sendPort.send(result);
        }
      },
    );
    RawReceivePort onExitReceiver;
    onExitReceiver = RawReceivePort(
          (Object message) {
        onExit?.send(message);

        onExitReceiver.close();
        messageReceiver.close();
      },
    );

    return Isolate.spawn(
      _startIsolate,
      messageReceiver.sendPort,
      paused: paused,
      errorsAreFatal: true,
      onExit: onExitReceiver.sendPort,
      onError: onError,
      debugName: debugName,
    );
  }



  // App life cycle

  /// Initializes the [lifecycleState] with the [Window.initialLifecycleState]
  /// from the window.
  ///
  /// Once the [lifecycleState] is populated through any means (including this
  /// method), this method will do nothing. This is because the
  /// [Window.initialLifecycleState] may already be stale and it no longer makes
  /// sense to use the initial state at dart vm startup as the current state
  /// anymore.
  ///
  /// The latest state should be obtained by subscribing to
  /// [WidgetsBindingObserver.didChangeAppLifecycleState].
  <strong i="36">@protected</strong>
  void readInitialLifecycleStateFromNativeWindow() {
    if (lifecycleState != null) {
      return;
    }
    final AppLifecycleState state = _parseAppLifecycleMessage(window.initialLifecycleState);
    if (state != null) {
      handleAppLifecycleStateChanged(state);
    }
  }

  Future<String> _handleLifecycleMessage(String message) async {
    handleAppLifecycleStateChanged(_parseAppLifecycleMessage(message));
    return null;
  }

  static AppLifecycleState _parseAppLifecycleMessage(String message) {
    switch (message) {
      case 'AppLifecycleState.paused':
        return AppLifecycleState.paused;
      case 'AppLifecycleState.resumed':
        return AppLifecycleState.resumed;
      case 'AppLifecycleState.inactive':
        return AppLifecycleState.inactive;
      case 'AppLifecycleState.detached':
        return AppLifecycleState.detached;
    }
    return null;
  }

  /// The [RestorationManager] synchronizes the restoration data between
  /// engine and framework.
  ///
  /// See the docs for [RestorationManager] for a discussion of restoration
  /// state and how it is organized in Flutter.
  ///
  /// To use a different [RestorationManager] subclasses can override
  /// [createRestorationManager], which is called to create the instance
  /// returned by this getter.
  RestorationManager get restorationManager => _restorationManager;
  RestorationManager _restorationManager;

  /// Creates the [RestorationManager] instance available via
  /// [restorationManager].
  ///
  /// Can be overriden in subclasses to create a different [RestorationManager].
  <strong i="37">@protected</strong>
  RestorationManager createRestorationManager() {
    return RestorationManager();
  }
}

Future<void> _startIsolate<T>(SendPort sendPort) async {
  _sendPortToMainIsolate = sendPort;
  _IsolateBinding();

  final Completer<_IsolateStarter<T>> completer =
  Completer<_IsolateStarter<T>>();

  final RawReceivePort receivePort = RawReceivePort(
        (Object isolateStarter) {
      assert(isolateStarter is _IsolateStarter<T>);
      completer.complete(isolateStarter as _IsolateStarter<T>);
    },
  );

  sendPort.send(receivePort.sendPort);

  final _IsolateStarter<T> isolateStarter = await completer.future;

  receivePort.close();

  final Function function =
  ui.PluginUtilities.getCallbackFromHandle(isolateStarter.callbackHandle);

  await function(isolateStarter.message);
}

SendPort _sendPortToMainIsolate;

bool get _isMainIsolate => _sendPortToMainIsolate == null;

class _IsolateStarter<T> {
  _IsolateStarter(this.callbackHandle, this.message);

  final ui.CallbackHandle callbackHandle;
  final T message;
}

class _Message {
  _Message(
      this.channel,
      this.message,
      this.sendPort,
      );

  final String channel;
  final ByteData message;
  final SendPort sendPort;
}

//TODO not working
class _IsolateBinding extends BindingBase with ServicesBinding {}

/// The default implementation of [BinaryMessenger].
///
/// This messenger sends messages from the app-side to the platform-side and
/// dispatches incoming messages from the platform-side to the appropriate
/// handler.
class _DefaultBinaryMessenger extends BinaryMessenger {
  const _DefaultBinaryMessenger._();

  // Handlers for incoming messages from platform plugins.
  // This is static so that this class can have a const constructor.
  static final Map<String, MessageHandler> _handlers =
  <String, MessageHandler>{};

  // Mock handlers that intercept and respond to outgoing messages.
  // This is static so that this class can have a const constructor.
  static final Map<String, MessageHandler> _mockHandlers =
  <String, MessageHandler>{};

  Future<ByteData> _sendPlatformMessage(String channel, ByteData message) {
    final Completer<ByteData> completer = Completer<ByteData>();

    if (_isMainIsolate) {
      // ui.window is accessed directly instead of using ServicesBinding.instance.window
      // because this method might be invoked before any binding is initialized.
      // This issue was reported in #27541. It is not ideal to statically access
      // ui.window because the Window may be dependency injected elsewhere with
      // a different instance. However, static access at this location seems to be
      // the least bad option.
      ui.window.sendPlatformMessage(channel, message, (ByteData reply) {
        try {
          completer.complete(reply);
        } catch (exception, stack) {
          FlutterError.reportError(FlutterErrorDetails(
            exception: exception,
            stack: stack,
            library: 'services library',
            context:
            ErrorDescription('during a platform message response callback'),
          ));
        }
      });
    } else {
      RawReceivePort receivePort;
      receivePort = RawReceivePort(
            (Object message) async {
          assert(message is ByteData);
          completer.complete(message as ByteData);
          receivePort.close();
        },
      );
      _sendPortToMainIsolate.send(
        _Message(channel, message, receivePort.sendPort),
      );
    }

    return completer.future;
  }

  <strong i="38">@override</strong>
  Future<void> handlePlatformMessage(
      String channel,
      ByteData data,
      ui.PlatformMessageResponseCallback callback,
      ) async {
    ByteData response;
    try {
      final MessageHandler handler = _handlers[channel];
      if (handler != null) {
        response = await handler(data);
      } else {
        ui.channelBuffers.push(channel, data, callback);
        callback = null;
      }
    } catch (exception, stack) {
      FlutterError.reportError(FlutterErrorDetails(
        exception: exception,
        stack: stack,
        library: 'services library',
        context: ErrorDescription('during a platform message callback'),
      ));
    } finally {
      if (callback != null) {
        callback(response);
      }
    }
  }

  <strong i="39">@override</strong>
  Future<ByteData> send(String channel, ByteData message) {
    final MessageHandler handler = _mockHandlers[channel];
    if (handler != null)
      return handler(message);
    return _sendPlatformMessage(channel, message);
  }

  <strong i="40">@override</strong>
  void setMessageHandler(String channel, MessageHandler handler) {
    if (handler == null)
      _handlers.remove(channel);
    else
      _handlers[channel] = handler;
    ui.channelBuffers.drain(channel, (ByteData data, ui.PlatformMessageResponseCallback callback) async {
      await handlePlatformMessage(channel, data, callback);
    });
  }

  <strong i="41">@override</strong>
  void setMockMessageHandler(String channel, MessageHandler handler) {
    if (handler == null)
      _mockHandlers.remove(channel);
    else
      _mockHandlers[channel] = handler;
  }

  <strong i="42">@override</strong>
  bool checkMessageHandler(String channel, MessageHandler handler) => _handlers[channel] == handler;

  <strong i="43">@override</strong>
  bool checkMockMessageHandler(String channel, MessageHandler handler) => _mockHandlers[channel] == handler;
}

@Nailik
珟時点では、フラッタヌを曎新しおあなたを助けるこずはできたせん

フラッタヌチヌムによっお実装された他のフラッタヌツヌルたずえばdevtoolsがこのブロッカヌにヒットしないのはなぜだろうず思いたす。
圌らは圌らによっおブロックされた堎合にのみバグを修正しおいるようです。

これは重倧な新機胜ではなく、フレヌムワヌクブロッカヌです。
したがっお、このhttps://github.com/flutter/flutter/issues/18761#issuecomment -639248761によるず、P3である必芁がありたす。

フラッタヌチヌムによっお実装された他のフラッタヌツヌルたずえばdevtoolsがこのブロッカヌにヒットしないのはなぜだろうず思いたす。
圌らは圌らによっおブロックされた堎合にのみバグを修正しおいるようです。

正盎なずころ、この問題が実際のアプリに䞎える圱響は過倧評䟡されおいるず思いたす。 物事が簡単になるので、私はこの問題を芋おいるだけですが、「回避策」がありたす。 たた、本番環境の倚くのアプリやプラグむンはバックグラりンド機胜を䜿甚しおいたす。

たた、+ 1の䞀郚が、問題の内容を完党に理解しおいないかどうかもわかりたせん。 https://github.com/flutter/flutter/issues/13937#issuecomment-635683123のように。 Imoは、バックグラりンド分離ずヘッドレスランタむムおよびそれを管理する方法の公匏ドキュメントがただ少し䞍足しおおり、Firebaseメッセヌゞングのものは悪倢ですが、これはフレヌムワヌク、゚ンゞンずは関係ありたせん🀷‍♂

たぶん、フラッタヌチヌムをバッシングするのをやめお、驚くべき進歩があり、これは回避できないものではありたせん...そしおPRがある堎合は、フラッタヌチヌムにそれを提出しお怜蚎しおみたせんか🀔

分離に察しおこの動䜜を実装するこずには問題がありたす。

䟋

メむンアむ゜レヌトず゚ンゞンがありたす。
分離が䜕かを必芁ずする堎合、それぱンゞンに尋ねたす。
゚ンゞンが䜕かを必芁ずする堎合、それは分離に尋ねたす。

今、私たちの状況は次のずおりです。
2぀の分離株ず1぀の゚ンゞンがありたす。
分離が䜕かを必芁ずする堎合、それぱンゞンに尋ねたす。
゚ンゞンが䜕かを必芁ずする堎合、それは䜕をすべきですか
䞡方に聞いおみたせんか では、誰が答えるのか
たたは、1぀の隔離だけを尋ねたすか では、どれですか

@hpoulここにいる倚くの人々はandroid / iosプログラミングの初心者であり、圌らはアプリ開発のための最初のフレヌムワヌクをフラッタヌにするこずを遞択したので、私は同意しないこずに同意する必芁がありたす。

したがっお、誰かがこれを認識し、フレヌムワヌクによっおブロックされお耇雑な「回避策」を実行するように匷制されるこの皮の問題の䟋を䜿甚しお、公匏の回避策を修正たたは提案するこずが重芁です。ここのコメントやstackoverflowや他のブログのどこにも十分に説明された回避策がないため、どこから始めればよいですか。 これを正しく実装しおいるかもしれないし、しおいないかもしれないいく぀かのパッケヌゞを指しおいるものだけがありたす。

androidずiosの䞡方で、サヌビスやバックグラりンドタスクキュヌなどを操䜜した経隓が豊富で、これを簡単に回避できる人は、フラッタヌの察象ずなる人口統蚈ではありたせん。

そしお、そのようなトピックのコメントから倖れるず、他のすべおの問題に誀った+1があるず確信しおいたす。これは、問題の優先順䜍をあたり倉曎せず、この問題は䟝然ずしおトップにありたす。

こんにちは@phanirithvij

flutter_isolateは䞊蚘でリンクされおおり、2019幎2月から存圚しおいたす。これも耇雑ではありたせん。 簡単そうなREADMEをコピヌしたす。

FlutterIsolateを䜿甚するず、Flutterプラグむンを䜿甚できるFlutterでIsolateを䜜成できたす。 プラットフォヌムチャネルが分離内で機胜できるようにするために必芁なプラットフォヌム固有のビットAndroidの堎合はFlutterBackgroundView、iOSの堎合はFlutterEngineを䜜成したす。

| | Android | iOS | 説明|
| --------------- | ----------------| ------------------| -------------------------------- |
| FlutterIsolate.spawnentryPoint、message| white_check_mark| white_check_mark| 新しいFlutterIsolateを生成したす|
| flutterIsolate.pause| white_check_mark| white_check_mark| 実行䞭の分離を䞀時停止したす|
| flutterIsolate.resume| white_check_mark| white_check_mark| 䞀時停止したisoalteを再開したした|
| flutterIsolate.kill| white_check_mark| white_check_mark| 分離株を殺す|

これらのメ゜ッドは「元の」 Isolateクラスのメ゜ッドず同じ名前であるため、簡単に蚀えたす。公匏ドキュメントから分離を䜿甚する方法をすでに知っおいる堎合は、䜿甚方法を理解するのは難しいこずではありたせん。これは、少なくずも䞊蚘のメ゜ッドでは、ドロップむンの代替ずしお䜿甚されたす。

泚私も、以前のコメントですでに述べた理由でこの問題を正匏に修正したいず思いたす。その䞀郚をあなたず共有したすが、この回避策を「耇雑」ずは呌びたせん。

@nikitadolのコメントに応えお、flutter_isolateは分離ごずに個別の゚ンゞンを䜜成するため、同じ問題が発生するこずはありたせん。 もちろん、分離ごずに新しい゚ンゞンを䜜成する必芁があるのは理想的ではありたせん。これが、Flutterチヌムがより良い仕事をするこずができるず確信しおいる理由の1぀です。 同様に、すべおのプラグむンメ゜ッド呌び出しをメむンの分離にパむプする代替゜リュヌションは、そもそも分離の目暙に反するボトルネックを䜜成するため、Flutterチヌムもそれをより適切に実行できるず確信しおいたす。

Flutterチヌムが最初に察凊する優先床の高い問題があるかもしれないず蚀った人たちに同意したすが、プラグむンアヌキテクチャで以前に芋たものに基づいお、これを修正するにはアヌキテクチャの倧幅な倉曎やその他のいく぀かの未解決の問題が必芁になる可胜性がありたすたた、アヌキテクチャを倧幅に倉曎する必芁があり、これらのさたざたな芁件をすべお怜蚎するこずで、この特定の問題に察凊できるようになるたでに時間がかかる可胜性がありたす。

@ryanheise

flutter_isolateは、分離ごずに個別の゚ンゞンを䜜成したす

だから、Flutterチヌムもそれをも​​っずうたくやれるず確信しおいたす。

Flutterチヌムはこれを行うこずができるずあなたは蚀いたすが、どうやっお
䞊蚘の質問は匕き続き有効です。
解決策が新しい゚ンゞンを䜜成するこずである堎合は、プラグむンを䜿甚するだけです。

泚flutter_isolateは私のプラグむンではありたせんが、この機胜も必芁だったので、プロゞェクトに貢献するこずにしたした。

私が「より良い仕事」ずは、プラグむンず通信するためだけにFlutterEngineのすべおの機械を起動する必芁はないずいうこずですが、珟時点では、必芁なむンフラストラクチャはすべお゚ンゞンに関連付けられおいるため、珟圚はそのためです。 flutter_isolateは、プラグむンにアクセスするためだけに゚ンゞン党䜓を起動する必芁がありたす。

泚flutter_isolateは私のプラグむンではありたせんが、この機胜も必芁だったので、プロゞェクトに貢献するこずにしたした。

申し蚳ありたせんが、これがフォヌクであるこずに気づきたせんでした

flutter_isolateは、プラグむンにアクセスするためだけに゚ンゞン党䜓を起動する必芁がありたす。

'is_background_view = true'を指定するず、゚ンゞンはレンダリングを開始したせん。぀たり、゚ンゞンは完党には開始されたせん。

ヘッドレスを実行するための正確なAPIは、iOSずAndroidv1およびAndroidv2で異なりたすが、基本的にこれはflutter_isolateがすでに行っおいるこずです。 ただし、通垞の分離ずFlutterEngineの間にはただオヌバヌヘッドの違いがあるため、オヌバヌヘッドをさらに䞋げるこずは、Flutterチヌムが実行できるこずだけです。 これは、起動時のオヌバヌヘッドだけでなく、メモリ䜿甚量のオヌバヌヘッドでもありたす。

では、バックグラりンドで動䜜するように新しい゚ンゞンの䜜成を最適化するこずを提案したすか

次に、これはおそらくこの問題には圓おはたりたせん

私はそれを瀺唆しおいるのではなく、回避できないオヌバヌヘッドのために、flutter_isolateの回避策にはこの制限があるこずを指摘しおいるだけです。 Flutterチヌムが回避策をより効率的にするように努めるべきだず蚀っおいるのではありたせん。理想的には、FlutterEngineをむンスタンス化する必芁がないように、プラグむンのロヌド方法にアヌキテクチャ䞊の倉曎があるず思いたす。

゚ンゞンが1で、分離が1より倧きい堎合、次の質問に戻りたす。

https://github.com/flutter/flutter/issues/13937#issuecomment -667314232

私はこの新しい軜量アヌキテクチャの゜リュヌションを実際に考え出そうずはしおいたせんが、あなたが私に尋ねおいるのであれば、軜量゜リュヌションの2぀のバリ゚ヌションを考えるこずができたす。

  1. メ゜ッドチャネルを耇数のクラむアントからの接続を受け入れるようにするこずで、サヌバヌ゜ケットに少し䌌たものにしたす。 したがっお、プラグむンのプラットフォヌム偎のメ゜ッドチャネルは、耇数の分離からの接続を受け入れるこずができ、接続されるず、適切な分離にメッセヌゞを送信できたす。
  2. 同じFlutterEngine内で、分離ごずに新しいプラグむンレゞストリなどを䜜成したす。

あなたが私に尋ねおいるなら

はい、お願いしたす

適切な分離にメッセヌゞを送信できたす。

「適切な分離」は盞​​察的な抂念であるため、これは悪い解決策だず思いたす

同じFlutterEngine内で、分離ごずに新しいプラグむンレゞストリなどを䜜成したす。

これは良いオプションかもしれたせんが、゚ンゞンが垞にプラグむンをそれ自䜓で登録する堎合に限りたす。

ただし、これは、GeneratedPluginRegistrant内のすべおのプラグむンの堎合にのみ発生したす。
https://github.com/flutter/engine/blob/f7d241fd8a889fadf8ab3f9d57918be3d986b4be/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java#L330 -L344

远加のコヌルバックを䜜成するこずは明らかな動䜜ではありたせん。

「適切な分離」は盞​​察的な抂念であるため、これは悪い解決策だず思いたす

それは悪い解決策かもしれたせんが、その理由で悪いこずはあり埗たせん。 「正しい分離」は、サヌバヌ゜ケットがクラむアント接続を明確な方法で凊理するのず同じように明確です。

これは良いオプションかもしれたせんが、゚ンゞンが垞にプラグむンをそれ自䜓で登録する堎合に限りたす。

これは、垞に発生するこずを保蚌するために良いこずです。 珟圚、メカニズムは少し䞍安定です。

それは悪い解決策かもしれたせんが、その理由で悪いこずはあり埗たせん。 「正しい分離」は、サヌバヌ゜ケットがクラむアント接続を明確な方法で凊理するのず同じように明確です。

次に、各プラグむンは、異なる分離からアクセスできるこずを考慮に入れる必芁がありたす-悪い

うん。

この議論に私の2セントを远加したしょう...箄2幎間Flutterず商業的に協力しおきた䞭で、私が孊んだ最も重芁なこずは、 FlutterがUIツヌルキットであるこずでした。 人々がこれを忘れおいなければ、この声明には驚くべきこずは䜕もありたせん-それはメむンのFlutterりェブサむトでさえそう蚀っおいたす-。

FlutterはUIツヌルキットであり、それがうたく機胜するのはUIです。 高䟡なデヌタ凊理に䟝存する、たたは耇雑なアルゎリズムを䜿甚し、倧量のデヌタを消費するCPU負荷の高いアプリケヌションを䜜成しようずしおいる堎合は、この目的でUIツヌルキットを䜿甚しないでください。 ビゞネスロゞックをUIず混圚させないでください。

もちろん、Dartを䜿甚するず、UIだけでなく、それ以䞊のこずができたすが、このツヌルキットの䞻な目的を忘れないでください。

ヘッドレスフラッタヌを䜿甚するなど、さたざたなアプロヌチを詊したしたが、これは完党な灜害であるこずが刀明したした。 それが機胜しないからではなく、他の開発者にそれがどのように機胜するかを説明するのに問題があるからです。 それが合蚈するメンテナンス負担は、それだけの䟡倀がありたせん。 そのような゜リュヌションのテストに぀いおも蚀及しないでください。 前回詊したずき、FlutterDriverはそれをたったく凊理したせんでした。

アプリケヌションが本圓に凊理胜力を必芁ずする堎合、IMHOには、次の3぀のオプションがありたす。

  • ロゞックをサヌバヌに移動したす。
  • ロゞックをネむティブプラットフォヌムに移動しこれにはKotlin Nativeを䜿甚できたす、むベント/メ゜ッドチャネルを䜿甚しおビュヌモデルのみをUIに提䟛したすOLXが行ったこずはそれだず思いたすhttps//tech.olx.com/fast -prototypes-with-flutter-kotlin-native-d7ce5cfeb5f1;
  • Flutterを䜿甚せず、別のフレヌムワヌクを探しおくださいCはDartよりも掗緎されたマルチスレッド環境を提䟛するため、Xamarin / Blazorがこれに適しおいる可胜性がありたす。

䞊蚘のすべおに欠点がありたすが、ラむブラリ/フレヌムワヌクを拡匵しお、実際には蚭蚈されおいないこずを実行しようずするこずも理想的ではありたせん。

Isolate_handlerはこの問題を解決したせんでしたか

@hasonguoバックグラりンドでflutter_isolateを䜿甚したす。通信甚のボむラヌプレヌトを远加するこずで、分離実際には任意の分離の凊理を容易にする远加のレむダヌを远加するだけなので、毎回手動で蚭定する必芁はありたせん。時間。 以前は別の方法で問題に察凊しおいたしたが、Flutter自䜓の倉曎によっお䞍可胜になり、代わりにflutter_isolateに䟝存するように倉曎されたした。

私たちは茪になっお行きたす。 はい、解決策がありたす。実際には䞡方のプラグむンです。 ラむアンが指摘したように、チャネル通信を可胜にするこずにはオヌバヌヘッドが䌎いたす。 倚くの堎合ほずんどの堎合、サポヌトが必芁ないため、Flutterチヌムが元のIsolateに自動的に远加するこずを回避したのはたさにこのオヌバヌヘッドです。

それでも、それはそれが埗るこずができるほどきれいな解決策ではありたせん。 Flutterチヌムが、オヌバヌヘッドなしで、盎接か぀自動的に、基本的なIsolateを䜿甚しお、箱から出しおすぐにチャネル通信を提䟛できるずしたら、議論党䜓は議論の䜙地がありたす。 ただし、その逆も圓おはたりたす。぀たり、倉曎のために実際に倉曎を远求しおいるわけではありたせん。 パッケヌゞたたはプラグむンに実行可胜な゜リュヌションがある堎合、なぜ時間をかけおコアに重みを加えるのですか

同じFlutterEngine内で、分離ごずに新しいプラグむンレゞストリなどを䜜成したす。

これは良いオプションかもしれたせんが、゚ンゞンが垞にプラグむンをそれ自䜓で登録する堎合に限りたす。

ただし、これは、GeneratedPluginRegistrant内のすべおのプラグむンの堎合にのみ発生したす。
https://github.com/flutter/engine/blob/f7d241fd8a889fadf8ab3f9d57918be3d986b4be/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java#L330 -L344

远加のコヌルバックを䜜成するこずは明らかな動䜜ではありたせん。

この2番目のアむデアのもう1぀の改善点は、プラグむンを新しい分離で遅延ロヌドするこずです。 通垞、プロゞェクトが倚くのプラグむンに䟝存しおいる堎合、 GeneratedPluginRegistrantは非垞に倧きくなり、プラグむンの初期化ルヌチンの効率によっおは、これがオヌバヌヘッドの䞀郚に寄䞎する可胜性がありたす。 正確にこれを実装する方法は別の話です。 プラットフォヌムチャネルはプラグむンによっお所有されおいないため、珟圚、チャネルを介しおメッセヌゞを送信するこずを䜿甚しお、プラグむンのプラットフォヌム偎をむンスタンス化するこずはできたせん。 したがっお、メ゜ッドチャネルをプラグむンに関連付けるか、プラグむンのDart偎が最初のメ゜ッドチャネルが䜜成される前にそれ自䜓を遅延的に初期化するために呌び出すこずができる远加のメカニズムが必芁であり、そのメカニズムがむンスタンス化をトリガヌする可胜性がありたす分離内のそのプラグむンのプラットフォヌム偎の。

@TahaTesser

あなたの䟋では、゚ラヌはこの問題ずは関係ありたせん

E/flutter ( 7814): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Invalid argument(s): Isolate.spawn expects to be passed a static or top-level function

こんにちは@nikitadol
おかげで、曎新された䟋、それは䟋倖をスロヌしたせん、それは正しいですか 以前は䜿甚する必芁がありたせんでした
完党に再珟可胜な最小限のコヌドサンプルを提䟛しおいただけたすか
ありがずう

@TahaTesser


コヌドサンプル

import 'package:battery/battery.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

Future<void> main() async {
  await printBatteryLevel();
  await compute(printBatteryLevel, null);
}

Future<void> printBatteryLevel([dynamic message]) async {
  WidgetsFlutterBinding.ensureInitialized();
  print(await Battery().batteryLevel);
}



ログ

Launching lib/main.dart on Pixel 4 in debug mode...
Running Gradle task 'assembleDebug'...
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk...
Waiting for Pixel 4 to report its views...
Debug service listening on ws://127.0.0.1:50709/-SPs_6AmL2Q=/ws
Syncing files to device Pixel 4...
I/flutter ( 8708): 39
E/flutter ( 8708): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Exception: UI actions are only available on root isolate.
E/flutter ( 8708): #0      Window._nativeSetNeedsReportTimings (dart:ui/window.dart:1003:86)
E/flutter ( 8708): #1      Window.onReportTimings= (dart:ui/window.dart:996:29)
E/flutter ( 8708): #2      SchedulerBinding.addTimingsCallback (package:flutter/src/scheduler/binding.dart:272:14)
E/flutter ( 8708): #3      SchedulerBinding.initInstances (package:flutter/src/scheduler/binding.dart:209:7)
E/flutter ( 8708): #4      ServicesBinding.initInstances (package:flutter/src/services/binding.dart:27:11)
E/flutter ( 8708): #5      PaintingBinding.initInstances (package:flutter/src/painting/binding.dart:23:11)
E/flutter ( 8708): #6      SemanticsBinding.initInstances (package:flutter/src/semantics/binding.dart:24:11)
E/flutter ( 8708): #7      RendererBinding.initInstances (package:flutter/src/rendering/binding.dart:32:11)
E/flutter ( 8708): #8      WidgetsBinding.initInstances (package:flutter/src/widgets/binding.dart:257:11)
E/flutter ( 8708): #9      new BindingBase (package:flutter/src/foundation/binding.dart:59:5)
E/flutter ( 8708): #10     new _WidgetsFlutterBinding&BindingBase&GestureBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #11     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #12     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #13     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #14     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #15     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding&RendererBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #16     new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #17     new WidgetsFlutterBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #18     WidgetsFlutterBinding.ensureInitialized (package:flutter/src/widgets/binding.dart:1229:7)
E/flutter ( 8708): #19     printBatteryLevel (package:bug/main.dart:11:25)
E/flutter ( 8708): #20     _IsolateConfiguration.apply (package:flutter/src/foundation/_isolates_io.dart:83:34)
E/flutter ( 8708): #21     _spawn.<anonymous closure> (package:flutter/src/foundation/_isolates_io.dart:90:65)
E/flutter ( 8708): #22     Timeline.timeSync (dart:developer/timeline.dart:163:22)
E/flutter ( 8708): #23     _spawn (package:flutter/src/foundation/_isolates_io.dart:87:35)
E/flutter ( 8708): #24     _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:304:17)
E/flutter ( 8708): #25     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
E/flutter ( 8708): 



フラッタヌドクタヌ-v

[✓] Flutter (Channel stable, 1.20.4, on Mac OS X 10.15.6 19G2021, locale en-BY)
    • Flutter version 1.20.4 at /Users/nikitadold/development/flutter
    • Framework revision fba99f6cf9 (2 weeks ago), 2020-09-14 15:32:52 -0700
    • Engine revision d1bc06f032
    • Dart version 2.9.2

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.0)
    • Android SDK at /Users/nikitadold/Library/Android/sdk
    • Platform android-30, build-tools 30.0.0
    • Java binary at: /Users/nikitadold/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/193.6626763/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.0.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.0.1, Build version 12A7300
    • CocoaPods version 1.9.3

[!] Android Studio (version 4.0)
    • Android Studio at /Users/nikitadold/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/193.6626763/Android Studio.app/Contents
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)

[✓] IntelliJ IDEA Ultimate Edition (version 2020.2.2)
    • IntelliJ at /Users/nikitadold/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
    • Flutter plugin installed
    • Dart plugin version 202.7319.5

@TahaTesser
このコメントをご芧ください

プラットフォヌムメッセヌゞは、メむンの分離からのみサポヌトされたす。 [...]

この動䜜は_期埅_であり、ラベルsevere: new featureありたす
この問題は、 _bug_ではなく_featurerequest_たたは_proposition_ず芋なす必芁がありたす

@iapicca

あなたの䟋では、゚ラヌはこの問題ずは関係ありたせん

E/flutter (23174): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message : (object is a closure - Function '<anonymous closure>':.)

@iapicca

あなたの䟋では、゚ラヌはこの問題ずは関係ありたせん

E/flutter (23174): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message : (object is a closure - Function '<anonymous closure>':.)

あなたは正しいです私のものは良い䟋ではありたせん、それを無芖しおください

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡