TransactionTooLargeException が発生した場合の対処方法 質問する

TransactionTooLargeException が発生した場合の対処方法 質問する

というエラーが出ましたTransactionTooLargeException。再現できません。ドキュメントにはこう書いてあります

バインダートランザクションは大きすぎるため失敗しました。

リモート プロシージャ コール中、コールの引数と戻り値は、Binder トランザクション バッファーに格納される Parcel オブジェクトとして転送されます。引数または戻り値が大きすぎてトランザクション バッファーに収まらない場合、コールは失敗し、TransactionTooLargeException がスローされます。

...

リモート プロシージャ コールが TransactionTooLargeException をスローした場合、2 つの結果が考えられます。クライアントがサービスに要求を送信できなかったか (引数が大きすぎてトランザクション バッファーに収まらない場合が考えられます)、サービスがクライアントに応答を返せなかったか (戻り値が大きすぎてトランザクション バッファーに収まらない場合が考えられます) のいずれかです。

...

つまり、どこかで、不明な制限を超える引数を渡したり受け取ったりしていることになります。どこでしょうか?

スタックトレースには何も役に立つ情報は表示されません:

java.lang.RuntimeException: Adding window failed
at android.view.ViewRootImpl.setView(ViewRootImpl.java:548)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:406)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
at android.view.Window$LocalWindowManager.addView(Window.java:557)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4977)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:569)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)
... 16 more
android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:569)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:406)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
at android.view.Window$LocalWindowManager.addView(Window.java:557)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4977)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)

ビューに関連しているようですが、これはリモート プロシージャ コールとどのように関連しているのでしょうか?

重要かもしれない: Android バージョン: 4.0.3、デバイス: HTC One X

ベストアンサー1

この問題に遭遇し、サービスとアプリケーション間で大量のデータが交換されるとき(多数のサムネイルの転送を含む)に発生することがわかりました。実際のデータ サイズは約 500 KB で、IPC トランザクション バッファ サイズは 1024 KB に設定されています。トランザクション バッファを超えた理由はわかりません。

これは、インテントエクストラを介して大量のデータを渡す場合にも発生する可能性があります。

アプリケーションでこの例外が発生した場合は、コードを分析してください。

  1. サービスとアプリケーション間で大量のデータを交換していますか?
  2. インテントを使用して膨大なデータを共有する(たとえば、ユーザーがギャラリー共有から大量のファイルを選択し、共有を押すと、選択したファイルの URI がインテントを使用して転送されます)
  3. サービスからビットマップファイルを受信
  4. Android が大量のデータを返すのを待つ (たとえば、ユーザーが多数のアプリケーションをインストールしたときの getInstalledApplications())
  5. 多くの操作が保留中の状態でapplyBatch()を使用する

この例外が発生した場合の対処方法

可能であれば、大きな操作を小さなチャンクに分割します。たとえば、1000 個の操作で applyBatch() を呼び出すのではなく、100 個ずつ呼び出します。

サービスとアプリケーション間で巨大なデータ(1MB以上)を交換しない

やり方はわかりませんが、膨大なデータが返される可能性がある Android にクエリを実行しないでください :-)

おすすめ記事