如何存储/排队要保存的多张照片以使它们都可以脱机使用?

时间:2018-07-07 20:03:22

标签: java android image image-processing offline

我目前可以保存图片:

String createImagePath = Constants.A_IMAGE + logo;
Bitmap img= getImageBitmapFromURL(this,createImagePath);
        new ImageSaver(this).
                setFileName(logo).
                setDirectoryName(Constants.IMAGE_DIR).
                save(img);

这是ImageSaver类:

public class ImageSaver {

    private String directoryName = "logo";
    private String fileName = "";
    private Context context;
    private boolean external;

    public ImageSaver(Context context) {
        this.context = context;
    }

    public ImageSaver setFileName(String fileName) {
        this.fileName = fileName;
        return this;
    }

    public ImageSaver setExternal(boolean external) {
        this.external = external;
        return this;
    }

    public ImageSaver setDirectoryName(String directoryName) {
        this.directoryName = directoryName;
        return this;
    }

    public void save(Bitmap bitmapImage) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(createFile());
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
            Log.d("THE PICTURE ", " The picture finished saving");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @NonNull
    private File createFile() {
        File directory;
        if(external){
            directory = getAlbumStorageDir(directoryName);
        }
        else {
            directory = context.getDir(directoryName, Context.MODE_PRIVATE);
        }
        if(!directory.exists() && !directory.mkdirs()){
            Log.e("ImageSaver","Error creating directory " + directory);
        }

        return new File(directory, fileName);
    }

    private File getAlbumStorageDir(String albumName) {
        return new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), albumName);
    }

    public static boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state);
    }

    public static boolean isExternalStorageReadable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state) ||
                Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
    }

    public Bitmap load() {
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(createFile());
            return BitmapFactory.decodeStream(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public boolean deleteFile(){ File file = createFile(); return file.delete(); }
}

我以后像这样加载图像:

 Bitmap bitmap = new ImageSaver(this).
                setFileName(logo).
                setDirectoryName(Constants.IMAGE_DIR).
                load();

        logoView.setImageBitmap(bitmap);

如果我将用于保存图像的代码放在for循环中,则会给我一个错误,这是有道理的,因为它工作过度,并且有太多文件异步工作。如何使它成为一个同步过程,或者有更好的方法应该这样做?

我想无限期地使所有图像脱机使用,但是最初会有时间将其连接到互联网以批量下载所有图像。如果花费很长时间没问题,我只需要允许它进行初始下载即可。最多可以包含100张图像。

1 个答案:

答案 0 :(得分:0)

听起来像是并发问题。

这可能不是您所需要的,但是您可以尝试一下!

使用

ConcurrentLinkedDeque<ImageSaver> saver;

在完成任何处理后将要保存的图像排队。

以此锁定先前的过程:

private final ReadWriteLock lock = new ReentrantReadWriteLock();

直到完成执行。

然后做:

if (lock.writeLock().tryLock()) {
    if (savePhotos()) {
        lock.writeLock().unlock();
        return true;
    }
    lock.writeLock().unlock();
}
return false;