1

Listview/customcursadapter を使用してレシピのリストを作成しました。ListViewカスタム レイアウトにはレシピの写真が含まれていますが、10 件のレコードしかありませんが (ターゲットは 150 件) 、表示とスクロールのパフォーマンスに問題があります。時々、このエラーが発生します。java.lang.OutOfMemoryError: bitmap size exceeds VM budget実装しようとしましたAsyncTaskが、失敗しました。この問題を克服する方法はありますか?

あなたの助けは大歓迎です!!

これが私のgetView方法です

public View getView(int position, View convertView, ViewGroup parent) {
    View row = super.getView(position, convertView, parent);
    Cursor cursbbn  = getCursor();
    if (row == null)
    {
        LayoutInflater inflater = (LayoutInflater) localContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = inflater.inflate(R.layout.listtype, null);
    }

    String Title = cursbbn.getString(2);
    String SandID=cursbbn.getString(1);
    String Readyin = cursbbn.getString(4);
    String Faovoites=cursbbn.getString(8);

    TextView titler=(TextView)row.findViewById(R.id.listmaintitle);
    TextView readyinr=(TextView)row.findViewById(R.id.listreadyin);

    int colorPos = position % colors.length;
    row.setBackgroundColor(colors[colorPos]);

    titler.setText(Title);
    readyinr.setText(Readyin);

    ImageView picture = (ImageView) row.findViewById(R.id.imageView1);

    Bitmap bitImg1 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0001);
    Bitmap bitImg2 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0002);
    Bitmap bitImg3 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0003);
    Bitmap bitImg4 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0004);
    Bitmap bitImg5 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0005);
    Bitmap bitImg6 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0006);
    Bitmap bitImg7 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0007);
    Bitmap bitImg8 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0008);
    Bitmap bitImg9 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0009);
    Bitmap bitImg10 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0010);

    if(SandID.contentEquals("0001"))
        picture.setImageBitmap(getRoundedCornerImage(bitImg1));

    if(SandID.contentEquals("0002"))
        picture.setImageBitmap(getRoundedCornerImage(bitImg2));

    if(SandID.contentEquals("0003"))
        picture.setImageBitmap(getRoundedCornerImage(bitImg3));

    if(SandID.contentEquals("0004"))
        picture.setImageBitmap(getRoundedCornerImage(bitImg4));

    if(SandID.contentEquals("0005"))
        picture.setImageBitmap(getRoundedCornerImage(bitImg5));

    if(SandID.contentEquals("0006"))
        picture.setImageBitmap(getRoundedCornerImage(bitImg6));
    if(SandID.contentEquals("0007"))
        picture.setImageBitmap(getRoundedCornerImage(bitImg7));
    if(SandID.contentEquals("0008"))
        picture.setImageBitmap(getRoundedCornerImage(bitImg8));
    if(SandID.contentEquals("0009"))
        picture.setImageBitmap(getRoundedCornerImage(bitImg9));

    if(SandID.contentEquals("0010"))
        picture.setImageBitmap(getRoundedCornerImage(bitImg10));

    return row;
}

そして、これはエラーです:

05-02 03:11:55.898: E/AndroidRuntime(376): FATAL EXCEPTION: main
05-02 03:11:55.898: E/AndroidRuntime(376): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:359)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:385)
05-02 03:11:55.898: E/AndroidRuntime(376):  at master.chef.mediamaster.AlternateRowCursorAdapter.getView(AlternateRowCursorAdapter.java:83)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.widget.AbsListView.obtainView(AbsListView.java:1409)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.widget.ListView.makeAndAddView(ListView.java:1745)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.widget.ListView.fillUp(ListView.java:700)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.widget.ListView.fillGap(ListView.java:646)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.widget.AbsListView.trackMotionScroll(AbsListView.java:3399)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.widget.AbsListView.onTouchEvent(AbsListView.java:2233)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.widget.ListView.onTouchEvent(ListView.java:3446)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.View.dispatchTouchEvent(View.java:3885)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
05-02 03:11:55.898: E/AndroidRuntime(376):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1691)
05-02 03:11:55.898: E/AndroidRuntime(376):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1125)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.app.Activity.dispatchTouchEvent(Activity.java:2096)
05-02 03:11:55.898: E/AndroidRuntime(376):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2194)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1878)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.os.Handler.dispatchMessage(Handler.java:99)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.os.Looper.loop(Looper.java:123)
05-02 03:11:55.898: E/AndroidRuntime(376):  at android.app.ActivityThread.main(ActivityThread.java:3683)
05-02 03:11:55.898: E/AndroidRuntime(376):  at java.lang.reflect.Method.invokeNative(Native Method)
05-02 03:11:55.898: E/AndroidRuntime(376):  at java.lang.reflect.Method.invoke(Method.java:507)
05-02 03:11:55.898: E/AndroidRuntime(376):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-02 03:11:55.898: E/AndroidRuntime(376):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-02 03:11:55.898: E/AndroidRuntime(376):  at dalvik.system.NativeStart.main(Native Method)
4

1 に答える 1

3

まず、convertView を使用していないため、次のように開始する必要があります。

View view = convertView;
if (view == null) {
  // inflate
}

convertView の使用について説明しているブログ投稿を次に示します。

http://android-er.blogspot.com/2010/06/using-convertview-in-getview-to-make.html

次に、使用することがわかっているビットマップのみをデコードする必要があります。メソッドを次のように変更します。

if(SandID.contentEquals("0001"))
    Bitmap bitImg1 = BitmapFactory.decodeResource(localContext.getResources(), R.drawable.rec0001);
    picture.setImageBitmap(getRoundedCornerImage(bitImg1));
...

第三に、それらを一度デコードして、この方法以外で利用できるようにすることはできますか? たとえば、コンストラクターで一度デコードし、インスタンス メンバーとしてアダプター クラスに格納してから、getView().

第 4 に、ビットマップをリサイクルしていますか? ビットマップは他のオブジェクトとは異なる方法で割り当てられ、recycle()使用が終了したらメソッドを呼び出す必要があります。上記の 3 番目の項目を実装できれば、この複雑さの大部分を回避できますが、アクティビティが停止したときに解放し、開始時に再割り当てする必要があります。

SO については有益な情報がたくさんありますBitmap.recycle()ので、時間をかけて調査することをお勧めします。複雑さを説明することは、ここの投稿で達成できることを超えています. これは、トピックをカバーする良いSO投稿の1つです。

Bitmap、Bitmap.recycle()、WeakReferences、ガベージ コレクション

于 2012-05-02T01:06:47.503 に答える