3

このようにウィジェットの1つのビットマップを更新しています(ウィジェット全体は1つのImageViewのみです)

remoteViews.setImageViewBitmap(...)

そして、いくつかのまれな状況(毎日の使用の6か月で3回発生しました)で、「!!! FAILED BINDER TRANSACTION !!!」が表示されます。次に、電話機の再起動のみがこの問題を解決します。アンインストールして再度インストールしても効果はなく、再起動するだけです。

アイコンのサイズを確認したところ、わずか 56 キロバイトであり、IPC メモリの制限内に収まっています。setImageViewBitmap(...) を削除すると、ウィジェットは再び機能しますが、ビットマップは更新されません。問題はビットマップ自体にあります。bitmal がこのように小さい場合、このバインダー トランザクションが失敗する原因は何ですか?

今のところ、アイコンを /data に保存することでこれを解決し、URI のみをウィジェットに送信しています。しかし、明らかにIPCメモリ制限に達していない場合、どこに問題があるのか​​ を知りたいですか?

編集:私は言及するのを忘れています、それはアンドロイド2.3.5と2.3.7でも起こりました

4

3 に答える 3

4

インテントで 1 mb 以上を解析できないようです。

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

Binder トランザクション バッファには、現在 1Mb の固定サイズが制限されており、プロセスで進行中のすべてのトランザクションで共有されます。したがって、個々のトランザクションのほとんどが中程度のサイズであっても、多数のトランザクションが進行中の場合、この例外がスローされる可能性があります。

リモート プロシージャ コールが TransactionTooLargeException をスローした場合、考えられる結果は 2 つあります。クライアントがサービスにリクエストを送信できなかったか (引数が大きすぎてトランザクション バッファに収まらない場合)、またはサービスがクライアントに応答を返すことができなかった (戻り値が大きすぎてトランザクション バッファに収まりません)。これらの結果のどれが実際に発生したかを判断することはできません。クライアントは、部分的な障害が発生したと想定する必要があります。

TransactionTooLargeException を回避するための鍵は、すべてのトランザクションを比較的小さく保つことです。リモート プロシージャ コールの引数と戻り値のパーセルを作成するために必要なメモリの量を最小限に抑えるようにしてください。文字列の巨大な配列や大きなビットマップを転送することは避けてください。可能であれば、大きなリクエストを小さな部分に分割してみてください。

サービスを実装している場合、クライアントが実行できるクエリにサイズまたは複雑さの制約を課すことが役立つ場合があります。たとえば、結果セットが大きくなる可能性がある場合は、クライアントが一度に複数のレコードを要求できないようにします。または、利用可能なすべてのデータを一度に返すのではなく、最初に重要な情報を返し、必要に応じて後でクライアントに追加情報を要求させます。

于 2012-04-23T13:31:59.843 に答える
2

これは、RemoteViews へのすべての変更がシリアル化されるために発生します ( setInt および setImageViewBitmap など)。ビットマップも内部バンドルにシリアル化されます。残念ながら、このバンドルには非常に小さいサイズ制限があります。

この方法で画像サイズを縮小することで解決できます。

public static Bitmap scaleDownBitmap(Bitmap photo, int newHeight, Context context) {

final float densityMultiplier = context.getResources().getDisplayMetrics().density;        

int h= (int) (newHeight*densityMultiplier);
int w= (int) (h * photo.getWidth()/((double) photo.getHeight()));

photo=Bitmap.createScaledBitmap(photo, w, h, true);

return photo;
}

newHeight を十分に小さくして (画面に表示される正方形ごとに ~100)、それをウィジェットに使用すると、問題は解決します:)

于 2011-12-31T14:23:24.243 に答える
1

remoteViews 変数を再利用していた場合: 同じ でビットマップを更新するたびにImageView、これは別のリモート ビュー アクションとして記録されます。に関連付けられているアクションのリストをクリアまたは重複排除する方法はありませんRemoteViews。この場合にできる唯一のことは、remoteVies を無限に再利用するのではなく、単に再作成することです

于 2015-10-16T12:25:41.383 に答える