2013-03-21 2 views
1

GridView을 앞뒤로 스크롤하면 내 이미지가 올바르게 재활용되지 않고 궁극적으로 그리드 전체에 동일한 이미지가 표시됩니다.Gridview 재활용 문제 asynctask

Recycling problem

어댑터

public class ImageAdapter extends BaseAdapter { 
    private Context mContext; 
    private List<String> mList; 
    private int mheight; 
    private int mwidth; 
    private Bitmap nBitmap; 

    public ImageAdapter(Context context, List<String> list, int height, int width) { 
     mContext = context; 
     mList = list; 
     mheight = height; 
     mwidth = width; 
    } 

    @Override 
    public int getCount() { 
     return mList.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return mList.get(position).toString(); 
    } 

    @Override 
    public long getItemId(int position) { 
     return 0; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ImageView imageView; 
     if (convertView == null) { 
      imageView = new ImageView(mContext); 
      InputStream is; 
      try { 
       is = mContext.getAssets().open(mList.get(position)); 
       Bitmap bm = BitmapFactory.decodeStream(is); 
       Bitmap mBitmap = Bitmap.createScaledBitmap(bm, mwidth/3, mwidth/3, false); 
       imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 

       this.nBitmap = mBitmap; 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } else { 
      imageView = (ImageView) convertView; 
     } 
     imageView.setImageBitmap(nBitmap); 
     return imageView; 
    } 
} 

내가 빨리 작업 UI 스레드 스크롤 오프 비트 맵 디코딩을 시도했지만 응용 프로그램을 시작할 때 썸네일이 1 일을로드하기 및 재활용 썸네일 변경 리스팅보기 orignal보기 및 낮은 낮은 memoery 장치에서 응용 프로그램 충돌 AsyncTask에서 축소판을로드하는 동안 여기서 업데이트 된 코드입니다

public class ImageAdapter extends BaseAdapter { 
private Context mContext; 
private List<String> mList; 
private int mheight; 
private int mwidth; 
private InputStream is; 

public ImageAdapter(Context context, List<String> list, int height, int width) { 
    mContext = context; 
    mList = list; 
    mheight = height; 
    mwidth = width; 
} 


@Override 
public int getCount() { 
    return mList.size(); 
} 

@Override 
public Object getItem(int position) { 
    return mList.get(position).toString(); 
} 

@Override 
public long getItemId(int position) { 
    return 0; 
} 





@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    ImageView imageView; 
    if (convertView == null) { 
     imageView = new ImageView(mContext); 
    } else { 
     imageView = (ImageView) convertView; 
    } 


    InputStream is; 
    try { 
     is = mContext.getAssets().open(mList.get(position)); 
     Loadimage task = new Loadimage(imageView , mheight , mwidth); 
     task.execute(is); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    return imageView ; 

} 
public class Loadimage extends AsyncTask<InputStream, Void, Bitmap>{ 
private final WeakReference<ImageView> imageViewReference; 


private InputStream is = null; 
private int width; 


public Loadimage(ImageView imageView, int mheight, int mwidth) { 
    imageViewReference = new WeakReference<ImageView>(imageView); 
    this.width=mwidth; 

    // TODO Auto-generated constructor stub 
} 

@Override 
protected Bitmap doInBackground(InputStream... params) { 
    is = params[0]; 

    if (is !=null) { 

     Bitmap bitmap = BitmapFactory.decodeStream(is); 
     Bitmap nBitmap =Bitmap.createScaledBitmap(bitmap,width/3 , width/3, false); 
     return nBitmap;  
    } 
    return null; 
    } 
@Override 
protected void onPostExecute(Bitmap bitmap) { 
    if (imageViewReference != null && bitmap != null) { 
     final ImageView imageView = imageViewReference.get(); 
     if (imageView != null) { 
      imageView.setImageBitmap(bitmap); 
      imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
     } 


} 

+0

을 = NULL, nBitmap 무엇입니까? 아마 마지막으로 거기에 적재 된 것이었을 것입니다. 비트 맵이로드되는 위치를 변경해야합니다. – eyespyus

+0

괜찮 으면 비트 맵을 다시로드하려고 할 때 스크롤이 매우 느리게됩니다. – Joseph27

답변

3

if/then 외부의 비트 맵을 생성하는 블록을 이동해야합니다. 지금은 convertView == null 일 때만 새로운 비트 맵을 생성합니다.

public class ImageAdapter extends BaseAdapter { 
    private Context mContext; 
    private List<String> mList; 
    private int mheight; 
    private int mwidth; 

    public ImageAdapter(Context context, List<String> list, int height, int width) { 
     mContext = context; 
     mList = list; 
     mheight = height; 
     mwidth = width; 
    } 

    @Override 
    public int getCount() { 
     return mList.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return mList.get(position).toString(); 
    } 

    @Override 
    public long getItemId(int position) { 
     return 0; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ImageView imageView; 
     if (convertView == null) { 
      imageView = new ImageView(mContext); 
     } else { 
      imageView = (ImageView) convertView; 
     } 

     InputStream is; 
     try { 
      is = mContext.getAssets().open(mList.get(position)); 
      Bitmap bm = BitmapFactory.decodeStream(is); 
      Bitmap bitmap = Bitmap.createScaledBitmap(bm, mwidth/3, mwidth/3, false); 
      imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 

      imageView.setImageBitmap(bitmap); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return imageView; 
    } 
} 

귀하의 스크롤이 매우 액체되지 않습니다 및 비트 맵 디코딩 코드가 비효율적이기 때문에 당신은 많은의 프레임을 떨어 얻을 것이다 (캐싱) :

나는 올바른 같은 코드가 될 것이다 생각 , 그리고 모두 UI 스레드에서 발생합니다. 이는 응답성에 좋지 않습니다. 현재 코드의 병목 현상은 ImageView의 할당 및 가비지 수집이 아닙니다.

병목 현상은 Bitmap의 처리 및 생성 (아마 멀리까지)입니다.

당신은 조언을 다음 링크에서 좀 걸릴 수 있습니다 : 특별히이 하나

Displaying Bitmaps Efficiently

와! 만약 convertView

Processing Bitmaps Off the UI Thread

+0

둘 다 시도했는데 전혀 재활용하지 않고 스크롤이 매우 뒤떨어져 있습니다. – Joseph27

+0

더 이상 재활용되지 않기 때문에 문제가 아니라고 확신합니다. 비트 맵 생성 속도가 느린 것 같습니다. 비트 맵 캐시가 있고 스트림을 디코딩하는 대신로드 한 경우와 그렇지 않은 경우를 비교하면 훨씬 빠릅니다. – yarian

+0

답변을 업데이트했습니다. – yarian