Android下载并在后台持有大量图片

时间:2014-05-18 13:11:39

标签: android android-asynctask download universal-image-loader

在我的Android应用程序中,我想下载一定数量的照片,这些照片链接到地图上的点。例如,我在地图上有十个点,每个点有5或6张照片。

一开始我每点得到5或6个网址(http://theimageurls.com/image.jpg),每张照片

  • 我想下载它们
  • 我想将它们保存在设备中。

当然,一切都是在后台完成的。 问题是,有时我的图像不会持久存在......但问题非常不规则,无论在什么图像上都会遇到...

这是我的代码:

对于每个点,都会调用 loadPictures()

private void loadPictures(final KickstartrGeolocPoint point) {

    //Photos : get directory path
    final File pointDir = FileUtils.getPointPhotoDir(getActivity(), point);

    //set boolean to true if the point has photos not downloaded.
    ArrayList<String> photosNotDownloaded = getPhotosNotDownloaded(point, pointDir);
    if(photosNotDownloaded.size()!=0){
        point.setPhoto(true);
        kickstartrGeolocService.updatePoint(currentPoint);
    }else{
        fillPointData(point);
        return;
    }

    //for each urls, download and save photo
    for(final String url : photosNotDownloaded){
        if (!Utils.isValidUrl(url)) continue;
        BitmapUtils.getBitmapFromUrl(url, new OnBitmapRetrievedListener() {
            @Override
            public void bitmapRetrieved(Bitmap bitmap) {
                LogWrapper.debug(getClass(), "Ready to be saved");
                persistImageforPoint(point, pointDir, bitmap, FileUtils.getFileNameFromUrl(url));
            }

            @Override
            public void onLoadingStarted(String imageUri, View view) {
                LogWrapper.debug(getClass(), "Image downloading... " + imageUri);
                //YOU CAN NOTIFY THE VIEW HERE
            }

            @Override
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                LogWrapper.debug(getClass(), "Loading failed : " + imageUri);
            }
        });
    }
}

getBitmapFromUrl()是一个静态方法,它使用名为https://github.com/nostra13/Android-Universal-Image-Loader的外部库。

getBitmapFromUrl()

public static void getBitmapFromUrl(String url, final OnBitmapRetrievedListener listener) {
    //final int maxSize = context.getResources().getDimensionPixelSize(R.dimen.icon_max_size);
    ImageLoader.getInstance().loadImage(url, new ImageLoadingListener() {
        @Override
        public void onLoadingStarted(String imageUri, View view) {
            listener.onLoadingStarted(imageUri,view);
        }

        @Override
        public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
            listener.onLoadingFailed(imageUri,view,failReason);
        }

        @Override
        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
            listener.bitmapRetrieved(loadedImage);
        }

        @Override
        public void onLoadingCancelled(String imageUri, View view) {
            //do nothing for the moment...
            // TODO notify the UI
        }
    });
}
调用

persistImageforPoint()来保存照片:

private void persistImageforPoint(KickstartrGeolocPoint point, File pointDir, Bitmap bitmap, String imageName) {
    // Create a subfolder for each point with its id
    if (!pointDir.exists()) {
        if (!pointDir.mkdirs()) {
            LogWrapper.debug(FileUtils.class, "Failed to create directory");
            return;
        }
    }

    final String fullPath = pointDir.getPath()+File.separator+FileUtils.getPointPhotoPrefix(point)+FileUtils.getFileNameFromUrl(imageName);

    //save the file. Asynchronous task --> do not block the UI
    new BitmapPersist(bitmap,fullPath, new OnBitmapPersistedListener() {
        @Override
        public void persistedSuccessfully() {
            addPhotoView(fullPath);
        }

        @Override
        public void errorInPersistance() {
            LogWrapper.error(getClass(),"Error persisting image with path "+fullPath);
        }
    }).execute();
}

这是我的 BitmapPersist 类:

public class BitmapPersist extends AsyncTask<String, Void, Boolean> {

private String path;
private Bitmap bitmap;
private OnBitmapPersistedListener onBitmapPersistedListener;

public BitmapPersist(Bitmap bitmap, String path, OnBitmapPersistedListener onBitmapPersistedListener) {
    this.bitmap=bitmap;
    this.path=path;
    this.onBitmapPersistedListener=onBitmapPersistedListener;
}

@Override
protected Boolean doInBackground(String... params) {
    FileOutputStream out = null;
    try {
        out = new FileOutputStream(path);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try{
            out.close();
        } catch(Throwable ignore) {}
    }
    return false;
}

@Override
protected void onPostExecute(Boolean success) {
    if (success)
        onBitmapPersistedListener.persistedSuccessfully();
    onBitmapPersistedListener.errorInPersistance();
}
}

问题:有时候我的图片没有保存,有时应用程序会崩溃......虽然所有内容都是在后台线程中完成的......

感谢您的帮助。

编辑: 也许我可以在我用来下载图片的库上添加精度:它是Android-Universal-Image-Loader(上面的链接)。此库适用于内存缓存和...磁盘缓存。也许我可以看看这个缓存。也许我可以改变磁盘缓存的路径并用它保存我的图片。我也在寻找知道这个库的人(由NOSTRA开发)......文档非常简洁......

解决方案: 不需要创建2个Asynctasks:同步下载图片,然后将其保存在同一个asynctask中。

0 个答案:

没有答案