15

Android 4.1 aでは、私にとって、一見奇妙なエラーがアプリで発生します。アプリでは、BaseAdapterを拡張するカスタムアダプターがギャラリーウィジェットに接続されています。左から右へ、またはその逆に高速でスクロールすると、例外メッセージが表示されたFCが表示されます。

java.lang.IllegalArgumentException:リサイクルされたビットマップを描画できません

getView(..)メソッドのコードは次のとおりです。

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;

    if (convertView == null){
        // View is not recycled. Inflate the layout.
        LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(R.layout.gallery_image, parent, false);

        viewHolder = new ViewHolder();
        viewHolder.image = (ImageView) convertView.findViewById(R.id.gallery_image);

        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder)convertView.getTag();
        viewHolder.image.setImageDrawable(null);
    }

    imageLoader.displayImage(images.get(position).getFilename(),
            images.get(position).getUrlThumbnail(),
            viewHolder.image,
            Math.round(BitmapUtil.convertDpToPixel(400f, context)),
            Math.round(BitmapUtil.convertDpToPixel(400f, context)));

    return convertView;
}

ImageViewをどこかでヌルにする必要があると思いますが、正しく機能させることができません。ImageLoaderは、画像をロードするための(非常に)単純なクラスです-LruCache、disk / sdcardから、またはリモートでフェッチします。

4

2 に答える 2

15

リサイクルされたビットマップにアクセスできないため、このエラーが発生します。Androidデベロッパーサイトが述べているように:

このビットマップに関連付けられているネイティブオブジェクトを解放し、ピクセルデータへの参照をクリアします。これは、ピクセルデータを同期的に解放しません。他に参照がない場合は、単にガベージコレクションを許可します。ビットマップは「デッド」としてマークされます。つまり、getPixels()またはsetPixels()が呼び出された場合は例外がスローされ、何も描画されません。この操作を元に戻すことはできないため、ビットマップをこれ以上使用しないことが確実な場合にのみ呼び出す必要があります。これは高度な呼び出しであり、通常は呼び出す必要はありません。これは、このビットマップへの参照がなくなると、通常のGCプロセスがこのメモリを解放するためです。

まだ使用されているので、この時点までビットマップをリサイクルしないことをお勧めします。したがって、メソッドを呼び出すときにコードを調べて、recycle()それを削除してください。

ビットマップを使用する必要がなくなったら、次の方法を使用してビットマップを破棄することをお勧めします。

public void disposeBitmap(Bitmap bitmap) {
        bitmap.recycle();
        bitmap = null;
}

これがお役に立てば幸いです。

于 2012-09-02T20:47:55.080 に答える
8

このエラーは、LruCacheをオーバーライドするクラスoldBitmap.recycle()のメソッドを呼び出すことによって発生したことがわかりました。entryRemoved(..)ビットマップがまだImageViewにアタッチされている可能性があるため、呼び出しrecycle()は問題を引き起こします。

私が正しく理解している場合:LruCacheのキャッシュサイズはコンストラクターで設定されます。アイテムの数がこのサイズを超えると、オブジェクトはガベージコレクションの対象になります。これは、ビットマップがImageViewに関連付けられなくなったときに発生します。

recycle()Webの周りの多くの例とチュートリアルは、で呼び出されるべきであることを示唆していますentryRemoved(..)が、私が見ることができることから、これは間違っています。

于 2012-09-18T11:38:04.453 に答える