Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saving and loading image with Picasso #1666

Closed
Dinchy87 opened this issue Aug 31, 2017 · 1 comment
Closed

Saving and loading image with Picasso #1666

Dinchy87 opened this issue Aug 31, 2017 · 1 comment

Comments

@Dinchy87
Copy link

I am trying to save an image with Picasso, i have the web url of the image, and i also have a specific filename for it. I tried to pass the .into() method to a Target which will save the image for me but the onBitmapLoaded Method is never called. Here is my code...

public static void imageDownload(Context ctx, String url, String filename) {
        try {
            Picasso.with(ctx).load(url).into(getTarget(filename));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

This above i call for the image download, Context is clear what it is, String url is the web url of the image and String filename is the File name i want to give the file in the Target run method later...

private static Target getTarget(final String fileName) {
        Target target = new Target() {

            @Override
            public void onBitmapLoaded(final Bitmap bitmap, final Picasso.LoadedFrom from) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                            Log.i(TAG, "The SD Card is not Mounted");
                        } else {
                            File file = new File(getFileName(fileName));
                            try {
                                FileOutputStream ostream = new FileOutputStream(file);
                                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
                                ostream.close();

                            } catch (Exception e) {
                                e.printStackTrace();
                                Log.e(TAG, e.getMessage());
                            }
                        }

                    }
                }).start();
            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {
            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {
            }
        };
        return target;
    }

And this is the method of obtaining the filename...

public static String getFileName(String fileName) {
        File file = new File(Environment.getExternalStorageDirectory().getPath(), "Images");
        if (!file.exists()) {
            file.mkdirs();
        }
        String uriSting = (file.getAbsolutePath() + "/" + fileName);
        return uriSting;
    }

Why the onBitmapLoaded is never called?! Any clue?

@JakeWharton
Copy link
Member

You are not retaining a strong reference to the Target and so it is being garbage collected. Picasso does not hold a strong reference to any target (be it a Target or ImageView, etc.). You need to store the Target somewhere so that it won't be collected. In this case there's not enough code to know who the caller of the method is, but usually they are the person which should be holding on to the reference in a field or something.

In general, though, is #506. And since you're not actually using Picasso to manipulate the image, I would recommend using your HTTP client (like OkHttp) directly to download the file as you can skip the needless decoding step and thread hopping and stream the bytes directly to disk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants