2

Я пытаюсь запросить все изображения на SD-карте через поставщика контента MediaStore и отобразить их миниатюру в GridView.Загрузка растрового изображения из контент-провайдеров с использованием asynctask

Однако, если я загрузить эскиз изображения на главном потоке, прокрутка становится невероятно медленно ...

Так я пытался загрузить растровый через asynctasks: производительности скроллинг стала лучше, но теперь элементы сетки держать их перезарядку миниатюры, пока не получит правильные растровое ...

Вот мой AsyncTask, который загружает растровые изображения:

package x.y; 

import java.lang.ref.WeakReference; 

import android.content.ContentResolver; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory.Options; 
import android.os.AsyncTask; 
import android.provider.MediaStore; 
import android.widget.ImageView; 

public class ImageThumbnailLoader extends AsyncTask<Long, Void, Bitmap> { 

    private final Options mOptions; 

    private WeakReference<ImageView> mImageViewWeakReference; 
    private ContentResolver mContentResolver; 

     public ImageThumbnailLoader(ImageView imageView, 
       ContentResolver cr) { 
     mContentResolver = cr; 
     mImageViewWeakReference = new WeakReference<ImageView>(imageView); 
     mOptions = new Options(); 
     mOptions.inSampleSize = 4; 
    } 



    @Override 
    protected Bitmap doInBackground(Long... params) { 
     Bitmap result; 
      result = MediaStore.Images.Thumbnails.getThumbnail(
        mContentResolver, params[0], 
        MediaStore.Images.Thumbnails.MINI_KIND, mOptions); 
     return result; 
    } 

    @Override 
    protected void onPostExecute(Bitmap result) { 
     super.onPostExecute(result); 
      if (mImageViewWeakReference != null 
        && mImageViewWeakReference.get() != null) 
       mImageViewWeakReference.get().setImageBitmap(result); 
    } 

} 

А вот мой пользовательский курсор адаптер:

package x.y; 

import android.content.Context; 
import android.database.Cursor; 
import android.graphics.BitmapFactory.Options; 
import android.provider.MediaStore; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.CursorAdapter; 
import android.widget.ImageView; 

public class MediaCursorAdapter extends CursorAdapter { 

    private LayoutInflater mInflater; 
    private final static int mColumnID = 0; 
    private Options mOptions; 

    public MediaCursorAdapter(Context context, Cursor c) { 
     super(context, c); 

     mInflater = LayoutInflater.from(context); 
     mOptions = new Options(); 
     mOptions.inSampleSize = 4; 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 

     ViewHolder holder = (ViewHolder) view.getTag(); 
     ImageThumbnailLoader imageLoader = new ImageThumbnailLoader(holder.thumbImg, 
       context.getContentResolver()); 
     imageLoader.execute(cursor.getLong(mColumnID)); 
//  holder.thumbImg.setImageBitmap(MediaStore.Images.Thumbnails.getThumbnail(
//     context.getContentResolver(), cursor.getLong(mColumnID), 
//     MediaStore.Images.Thumbnails.MINI_KIND, mOptions)); 
     Log.i("Prototype", "bindView : " + cursor.getPosition()); 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 
     Log.i("Prototype", "newView : " + cursor.getPosition()); 
     View view = mInflater.inflate(R.layout.grid_item, null); 
     ViewHolder holder = new ViewHolder(view); 
     view.setTag(holder); 
     return view; 
    } 


    private static class ViewHolder { 
     ImageView thumbImg, dragImg; 

     ViewHolder(View base) { 
      thumbImg = (ImageView) base.findViewById(R.id.thumbImage); 
      dragImg = (ImageView) base.findViewById(R.id.dragImage); 
     } 
    } 

} 

я запрашиваю курсор с этим кодом и отправить его к адаптеру:

query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] { MediaStore.Images.Media._ID, 
      MediaStore.Images.Media.DATA }, null, null, 
    MediaStore.Images.Media._ID); 

Похоже BindView() на мой пользовательский адаптер курсора вызывается чаще, чем это предполагается ... Кто-нибудь знает, как я могу сделать изображения на моем gridview прекратить перезагрузку, сохраняя производительность прокрутки?

Заранее спасибо.

ответ

7

Проблема решена, пришлось проверить, было ли изображение в начале задачи async таким же, как изображение в конце его, onPostExecute().

новый BindView:

@Override 
    public void bindView(View view, Context context, Cursor cursor) { 

     ViewHolder holder = (ViewHolder) view.getTag(); 
     holder.thumbImg.setId(cursor.getPosition()); 
     ImageThumbnailLoader imageLoader = new ImageThumbnailLoader(holder.thumbImg, 
      context.getContentResolver()); 
     imageLoader.execute(cursor.getLong(mColumnID)); 
    Log.i("Prototype", "bindView : " + cursor.getPosition()); 
    } 

новый Асинхронный:

public class ImageThumbnailLoader extends AsyncTask<Long, Void, Bitmap> { 

    private final Options mOptions; 

    private WeakReference<ImageView> mImageViewWeakReference; 
    private ContentResolver mContentResolver; 
    private int mPosition; 


     public ImageThumbnailLoader(ImageView imageView, 
      ContentResolver cr) { 
     mContentResolver = cr; 
     mImageViewWeakReference = new WeakReference<ImageView>(imageView); 
     mOptions = new Options(); 
     mOptions.inSampleSize = 4; 
     mPosition = imageView.getId(); 
    } 



    @Override 
    protected Bitmap doInBackground(Long... params) { 
     Bitmap result; 
      result = MediaStore.Images.Thumbnails.getThumbnail(
       mContentResolver, params[0], 
       MediaStore.Images.Thumbnails.MINI_KIND, mOptions); 
     return result; 
    } 

    @Override 
    protected void onPostExecute(Bitmap result) { 
     super.onPostExecute(result); 
      if (mImageViewWeakReference != null 
        && mImageViewWeakReference.get() != null 
         && mPosition == mImageViewWeakReference.get().getId()) 
       mImageViewWeakReference.get().setImageBitmap(result); 
    } 

} 
Смежные вопросы