【问题标题】:Load GridView Bitmaps in Asynctask在 Asynctask 中加载 GridView 位图
【发布时间】:2018-12-18 03:41:14
【问题描述】:

是否可以在异步任务中加载 GridView 的缩略图,以防止滚动 GridView 时出现滞后?

这是我的 Asynctask 的代码:

@SuppressLint("StaticFieldLeak")
public class AsyncTaskLoadFiles2 extends AsyncTask<Void, String, Void> {

    File targetDirector;


    public AsyncTaskLoadFiles2(ImageAdapter2 adapter) {
        myTaskAdapter2 = adapter;
    }

    @Override
    protected void onPreExecute() {


        String targetPath = "/sdcard/Android/data/de.myapps.gridtest/files/Download/.Videos";
        targetDirector = new File(targetPath);
        myTaskAdapter2.clear2();

        progressDialog = new ProgressDialog(getContext());
        progressDialog.setMessage("Loading Videos, please wait...");
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setCancelable(false);
        progressDialog.show();


        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {

        File[] files = targetDirector.listFiles();
        for (File file : files) {
            publishProgress(file.getAbsolutePath());

            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (isCancelled()) break;
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {

        myTaskAdapter2.add2(values[0]);


        super.onProgressUpdate(values);
    }


    @Override
    protected void onPostExecute(Void result) {

        myTaskAdapter2.notifyDataSetChanged();

        progressDialog.dismiss();

        super.onPostExecute(result);
    }

}

这是我的 ImageAdapter 的代码:

public class ImageAdapter2 extends BaseAdapter {

    private Context mContext;
    ArrayList<String> itemList = new ArrayList<String>();

    public ImageAdapter2(Context c) {
        mContext = c;
    }

    void add2(String path) {
        itemList.add(path);
    }

    void clear2() {
        itemList.clear();
    }

    void remove2(int index) {
        itemList.remove(index);
    }


    public String getPath(int position) {
        return itemList.get(position);
    }

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

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return itemList.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    @SuppressLint("ResourceType")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) { 
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 420));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        } else {
            imageView = (ImageView) convertView;
        }

        thumbnail = ThumbnailUtils.createVideoThumbnail(getPath(position),
                MediaStore.Images.Thumbnails.MICRO_KIND);

            // Set the decoded bitmap into ImageView
            imageView.setImageBitmap(thumbnail);



        return imageView;
    }

}

所以我想知道是否可以在 Asynctask 中加载 thumbnail 位图,因为使用此代码,应用程序会滞后。 (我使用的是 TabbedActivity,所以所有这些代码都是 Fragment 的一部分)

【问题讨论】:

    标签: android performance video gridview android-asynctask


    【解决方案1】:

    看看

    https://developer.android.com/topic/performance/graphics/cache-bitmap

    BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
    task.execute(resId);
    

    您可以创建一个将图像加载到 ImageView 中的 AsyncTask

    class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
        ...
        // Decode image in background.
        @Override
        protected Bitmap doInBackground(Integer... params) {
            final Bitmap bitmap = decodeSampledBitmapFromResource(getResources(), params[0], 100, 100));
            return bitmap;
        }
    
        @Override
        protected void onPostExecute(Bitmap result) {
             if(result != null) {
                 myImgView.setImageBitmap(result);
             }
        }
    }
    

    您只需通过适配器中的getView() 方法在构造函数中使用参数调用BitmapWorkerTask.Execute

    BitmapWorkerTask task = new BitmapWorkerTask(imageView, filePath);
    

    制作构造函数

    class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
        private ImageView imageView;
        private String filePath;
    
        public BitmapWorkerTask(ImageView imageView, String filePath) {
            this.imageView = imageView;
            this.filePath = filePath;
        }
        ....
        //Get your bitmap
        //Set Bitmap onPostExecute
    

    【讨论】:

    • 但是 '... = new BitmapWorkerTask(mImageView)' 只为一个 ImageView 加载位图,对吧?我想使用 Gridview,所以我必须加载许多位图。有可能吗?
    • 是的,您的 getView() 方法会为每个 GridView 项目调用...
    • 因此,对于 gridview 中的每个项目,您将调用 imageView = new ImageView(mContext); 然后 ... = new BitmapWorkerTask(imageView, ...)
    • @NilsBe 所以for (File file : files) { 循环将发生在ImageAdapter2 之外,您将适配器设置为gridview,您将list of filePaths 传递给适配器。然后你在getView 方法中使用AsyncTask 设置图像
    猜你喜欢
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多