替换自定义适配器中的图像 - AsyncTask /多线程

时间:2014-04-15 13:30:11

标签: android android-listview android-asynctask

我所拥有的是AsyncTask,它会加载文件和文件夹列表,并使用我的自定义适配器将它们放入我的自定义Listview中。

此自定义Listview具有ImageView和TextView。

当列表最初加载时,我为每个文件和文件夹加载一个“虚拟”图像(我只使用一个drawable)。我这样做,所以列表加载很快。

完成第一个Async任务后,我想用REAL图像缩略图替换任何虚拟可绘制图像(这来自Dropbox)。

所以 - 做这部分我只是开始另一个AsyncTask这样做。它逐个加载每个缩略图,并用适当的替换适配器中的默认虚拟图像。

我使用onProgressUpdate刷新适配器,以便在下载每个缩略图后更新ListView。它似乎工作正常,图像被下载,替换,用户仍然可以在图像更新时滚动。

问题: 它很慢。需要1-2秒才能检索单个缩略图并加载它。

问题:

  1. 有没有办法可以让多个线程下载 缩略图,所以他们分批装载例如一次10个?没有冻结UI!

  2. 我看到的问题是知道适配器放在哪里 缩略图一旦下载(请参阅我的代码,了解我的方式 目前使用int计数器执行此操作。

  3. 这是我的AsyncTask,用于获取真实的缩略图并替换虚拟图像。它一次从Dropbox下载图像。如果我能在多个线程中做到这一点,那就好了!

     private class loadActualThumbs extends AsyncTask<DbxFileSystem, Integer, Boolean> {
    
            @Override
            protected  void onPreExecute()
            {
    
            }
            @Override
            protected Boolean  doInBackground(DbxFileSystem... params) {
                //Opens thumbnails for each image contained in the dropbox folder
                try {
                    DbxFileSystem fileSystem = params[0];
                    DbxFile file = null;
                    int loopCount=0; //I use this to identify where in the adapter the real image should go
    
                    for (DbxFileInfo fileInfo: fileSystem.listFolder(currentPath)) {
    
                        try{
    
                            if(fileInfo.thumbExists) // if it has a thumbnail then retrieve it
                            {
                                file = fileSystem.openThumbnail(fileInfo.path, ThumbSize.S, ThumbFormat.PNG);
                                Bitmap image = BitmapFactory.decodeStream(file.getReadStream());
                                pix.set(loopCount,image); //replace the default image with the real one
                                loopCount++;
                                publishProgress(1);
                            }
                            else
                            {
                                // its a folder so no image needed
                                loopCount++;//still need to increment this though
    
                            }
                        }
                        catch(Exception e)
                        {
                            e.printStackTrace();
                        }
                        System.gc();
                    }
    
                    file.close(); //close the file outside of the loop
    
                }
                catch (Exception e) {
                    e.printStackTrace();
                    return false;
                } finally {
    
                }
                return true;
            }
            @Override
            protected void onProgressUpdate(Integer...progress) {
    
                   //we want to load the image here to the adapter
                adapter.notifyDataSetChanged();
                super.onProgressUpdate(progress);
            }
            @Override
            protected void onPostExecute(Boolean result) {
    
    
            }
    }
    

1 个答案:

答案 0 :(得分:0)

看看Universal Image Loader。它会在后台加载所有图像,如果需要可以缓存它们,并且可以设置一次下载的数量(线程数)。