2012-05-02 3 views
1

Listview/customcursoradapter를 사용하여 래서 피 목록을 만들었습니다. 사용자 정의 레이아웃에는 레서피 용 사진이 포함되어 있지만 이제는 레코드가 10 개 (대상은 150 개)이지만 ListView의보기 및 스크롤 성능과 관련된 몇 가지 문제가 있습니다. 때로는이 오류 java.lang.OutOfMemoryError: bitmap size exceeds VM budget을 얻었으므로 AsyncTask을 구현하려했지만 실패했습니다. 이 문제를 극복 할 수있는 방법이 있습니까?ListView 성능 저하

귀하의 도움에 감사드립니다 !! 여기

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) 

답변

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()에서 사용하면됩니다.

넷째, 비트 맵을 재활용하고 있습니까? 비트 맵은 다른 객체와 다르게 할당되며 사용을 마친 후에는 recycle() 메소드를 호출해야합니다. 위의 세 번째 항목을 구현할 수 있다면 대부분의 경우 이러한 복잡성을 피할 수 있습니다. 활동이 중지 될 때 해제해야하지만 시작할 때 다시 할당해야합니다.

많은 좋은 정보가 Bitmap.recycle()에 관한 것이므로 조사하는 데 시간을 투자 할 것을 권장합니다. 복잡함을 설명하는 것은 여기에 게시 할 수있는 것을 넘어서고 있습니다. 여기가 변환보기를 구현하기 위해 노력했습니다

Bitmap, Bitmap.recycle(), WeakReferences, and Garbage Collection

+0

좋은 SO 주제를 다루는 게시 하나입니다하지만 난 동일한 이름을 가진 10 개 개의 레코드를 얻을 ??? –

+0

그것의 경우 내가보기 행 = super.getView (위치, convertView, 부모)를 사용하지; –

+0

변환보기는 "재활용 된"보기입니다. 모든 값을 다양한 text/image/etc보기로 설정해야합니다. 유일한 차이점은 비용이 많이 드는 새 뷰를 부 풀리는 것을 피할 수 있다는 것입니다. –