2015-01-23 2 views
-1

내부 저장소에서 목록보기로 축소판 형태로 그림 파일을로드하려고합니다. 현재 ViewHolder를 사용하고 있지만 스크롤 할 때로드가 계속 고르지 않아서 AsyncTask를 사용하려고합니다. 그러나 나는 웹 사이트에서 다운로드를 처리하는 대부분의 예제처럼 AsyncTask를 구조화하는 방법에 대해 머리를 맞출 수가 없다. 내 BaseAdapter 또는 내 MainActivity 하위 클래스 해야하는 경우에도 잘 모르겠습니다. 아래쪽에 미완성 AsyncTask가있는 baseadapter를 아래에 추가했습니다. AsyncTask를 사용하여 ViewHolder를 지원하거나 직접 AsyncTask에 이미지를 전달하고 ListView가 원활하게 스크롤되도록 비트 맵을 반환하도록하려면 어떻게 구성해야합니까?AsyncTask를 사용하여 내부 저장소에서 이미지 파일로드

public class ListViewAdapter extends BaseAdapter { 

private static final int WIDTH = 250; 
private static final int HEIGHT = 250; 
private static final int ROTATION = 90; 

private final static String TAG = "Pictures"; 

private final ArrayList<SelfieObject> mItems = new ArrayList<SelfieObject>(); 
private Context mContext; 
private File mStorageDir; 
private String mFilePrefix; 

public ListViewAdapter(Context context, File storageDir, String filePrefix) { 
    mContext = context; 
    mStorageDir = storageDir; 
    mFilePrefix = filePrefix; 

    //get file list from storage to display 
    InitializeItemsFromStorage(storageDir, filePrefix); 
} 

//this method creates an array of files stored on the device or SD card. 
private void InitializeItemsFromStorage(File storageDir, String prefix) { 

    log("in InitializeItemsFromStorage()"); 
    mItems.clear(); 

    File[] files = getFiles(storageDir, prefix); 
    for (File f : files) { 
     SelfieObject selfie = new SelfieObject(f); 
     mItems.add(selfie); 
    } 

} 

public void Update() { 

    log("in Update()"); 
    InitializeItemsFromStorage(mStorageDir, mFilePrefix); 
    notifyDataSetChanged(); 
} 

/* 
* return the list of file objects of the given directory that begin with 
* the prefix. 
*/ 
private File[] getFiles(File storageDir, final String prefix) { 
    FileFilter fileFilter = new FileFilter() { 

     @Override 
     public boolean accept(File pathname) { 
      if (pathname.isFile() && pathname.getName().startsWith(prefix)) 
       return true; 
      else 
       return false; 
     } 
    }; 

    File[] result = storageDir.listFiles(fileFilter); 
    return result; 
} 

public int getCount() { 

    log("in getCount()"); 
    return mItems.size(); 
} 

public Object getItem(int position) { 

    log("in getItem()"); 
    return mItems.get(position); 
} 

public long getItemId(int position) { 

    log("in getItemId()"); 
    return position; 
} 

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

    Log.v(TAG, "in getView for position " + position + 
      ", convertView is " + 
      ((convertView == null)?"null":"being recycled")); 

    View newView = convertView; 
    ViewHolder holder; 

    if (null == convertView) { 

     LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     newView = inflater.inflate(R.layout.single_item, null); 

     holder = new ViewHolder(); 
     holder.description = (TextView) newView.findViewById(R.id.textView1); 
     holder.picture = (ImageView) newView.findViewById(R.id.imageView1); 
     newView.setTag(holder); 

    } else { 
     holder = (ViewHolder) newView.getTag(); 
    } 

    holder.picture.setScaleType(ImageView.ScaleType.CENTER_CROP); 

    SelfieObject selfie = (SelfieObject) getItem(position); 
    setPic(holder.picture, new Point(WIDTH, HEIGHT), selfie.getPath()); 

    TextView textView = (TextView) holder.description; 
    textView.setText(selfie.getName());  

    log("Exiting getView"); 
    return newView; 
} 

static class ViewHolder { 

    ImageView picture; 
    TextView description; 
} 

public void add(SelfieObject listItem) { 
    mItems.add(listItem); 
    notifyDataSetChanged(); 
} 

public ArrayList<SelfieObject> getList(){ 
    return mItems; 
} 

public void removeAllViews(){ 
    mItems.clear(); 
    this.notifyDataSetChanged(); 
} 

public static void setPic(ImageView imageView, Point requestedSize, 
     String pathName) { 
    // set the dimensions of the View 
    int targetW = requestedSize.x; 
    int targetH = requestedSize.y; 

    // Get the dimensions of the bitmap 
    BitmapFactory.Options bmOptions = new BitmapFactory.Options(); 
    bmOptions.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(pathName, bmOptions); 
    int photoW = bmOptions.outWidth; 
    int photoH = bmOptions.outHeight; 

    // Determine how much to scale down the image 
    int scaleFactor = Math.min(photoW/targetW, photoH/targetH); 

    // Decode the image file into a Bitmap sized to fill the View 
    bmOptions.inJustDecodeBounds = false; 
    bmOptions.inSampleSize = scaleFactor; 
    bmOptions.inPurgeable = true; 

    Bitmap bitmap = BitmapFactory.decodeFile(pathName, bmOptions); 
    imageView.setImageBitmap(bitmap); 
    imageView.setRotation(ROTATION); 
} 

//Automation logging tool 
public void log(String s){ 

    Log.i(TAG, s); 
} 

private class AsyncTaskLoadImage extends AsyncTask<Object, Void, Bitmap>{ 

    private ImageView image; 
    private String path; 

    public AsyncTaskLoadImage(ImageView image){ 

     this.image = image; 
     this.path = image.getTag().toString(); 
    } 

    @Override 
    protected Bitmap doInBackground(Object... params) { 

     Bitmap bitmap = null; 
     File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + path); 

     if(file.exists()){ 
      bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); 
     } 

     return bitmap; 
    } 
} 

}

답변

1

AsyncTask를이 UI 스레드에서 할 너무 느린 무엇이든해야한다. 이 예제에서는 이미지를 가져 와서 다운 샘플링하고 ViewHolder를 설정하는 작업을 백그라운드에서 수행해야합니다. 그렇지 않으면 소비하는 것, 내가보기 엔 당신이 당신의 비트 맵을 다운 샘플링 제안, 또한 https://github.com/lucasr/smoothie

그러나

, 나는 당신이 시도하고 혼자서 목록보기 수정, 오히려 같은 기존 솔루션을 한 번 봐,이없는 제안 과도한 컴퓨팅 시간과 메모리가 많이 필요합니다. 이전 버전에서는 스크롤 할 때 UI가 지연 될 수 있지만 후자는 멋진 OutOfMemoryException을 얻을 수 있습니다. 참조 : http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

+0

실제로 필자는 로딩에 대한 도움을 받기 위해 Piccaso를보고 있었지만, 적어도 한 번은 수동으로 모든 작업을 수행하려고 노력 중이므로 (학습 경험으로) 어떤 일이 일어나고 있는지 이해할 수 있습니다. 내 setPic이 비트 맵 크기를 줄이기 위해 트릭을했을지도 모른다. listview는 섬네일을 잘로드하지만 새로운보기마다 목록을로드 할 때 500ms의 지연 시간을 쉽게 볼 수 있습니다. AsyncTask가 도움이되기를 바랬습니다. –