1. ホーム
  2. アンドロイド

[解決済み】TransactionTooLargeExceptionが発生した場合の対処方法

2022-04-15 05:55:23

質問

を取得しました。 TransactionTooLargeException . 再現性がない。ドキュメントには次のように書かれています。

Binder トランザクションが大きすぎたため、失敗しました。

リモートプロシージャ呼び出しの際、呼び出しの引数と戻り値は、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

解決するには?

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

この現象は、大量のデータをインテントに渡した場合にも発生することがあります。

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

  1. サービスとアプリケーションの間で大量のデータをやり取りしていませんか?
  2. 巨大なデータを共有するためにインテントを使用する(例えば、ユーザーがギャラリー共有プレス共有から膨大な数のファイルを選択すると、選択したファイルのURIはインテントを使用して転送されます)。
  3. サービスからのビットマップファイルの受信
  4. アンドロイドが巨大なデータで応答するのを待つ(例えば、ユーザーが多くのアプリケーションをインストールした場合、getInstalledApplications())。
  5. 多くの処理を保留している状態でapplyBatch()を使用した場合

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

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

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

どうすればいいのかわからないのですが、アンドロイドに問い合わせると巨大なデータを返してしまうので、問い合わせないようにしましょう :-)