简体   繁体   中英

How to store/queue multiple photos to be saved to make them all available offline?

I am currently able to save an image:

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

This is the ImageSaver Class:

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(); }
}

I later load the image like so:

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

        logoView.setImageBitmap(bitmap);

If I put the code for save the image in a for loop it will give me an error, which makes sense since it is overworking it and has too many files working async-ly. How do I make this a synced process or is there a better way I should be doing this?

I want to make all images available offline indefinitely, but there will be the initial time where it will be connected to the internet to download all the images in one batch. If it takes long that is fine, I just need to allow it to do that initial download. This can be up to a 100 images.

Sounds like a concurrency issue.

This may not be what you neccessarily need, but you can try this!

Use a

ConcurrentLinkedDeque<ImageSaver> saver;

To queue the images which you wish to save after whatever process finishes executing.

Lock the previous process with this:

private final ReadWriteLock lock = new ReentrantReadWriteLock();

Until it has finished its execution.

Then do:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM