Search code examples
javaandroidimagepicasso

Downloading images using Picasso creates incorrect images in cache, possible fix?


I have a Realm database with image URLs, and I need to download these images in the ExternalCacheDir . Now here lies the problem : assume I have three images : ar11.jpg,ar12.jpg,ar13.jpg . Once my code is executed, I obtain 3 jpg images in the cache dir, with the above mentioned names, however all three images are the replicas of the last image, ie ar13.jpg with the names ar11,ar12,ar13.

Here is my code:

 private void downloadImage()
{
    RealmResults<ARDatabase> results = mRealm.where(ARDatabase.class).findAll();

    for(ARDatabase x:results)
    {
        if(!x.getIsDownloaded())
        {
            mdataCollection.add(new DownLoadList(x.getUrlImg(),x.getUid()));
        }
    }

    for(DownLoadList i:mdataCollection)
    {
        Log.e("Link",""+i.getImageUrl());
        Picasso.with(getApplicationContext()).load(i.getImageUrl()).into(target);
    }
}

 private Target target = new Target() {
    @Override
    public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from)
    {
        Log.e("PICASSO","SUCCESSFUL");


        new Thread(new Runnable() {
            @Override
            public void run() {

                File sd = getExternalCacheDir();
                File folder = new File(sd, "/arproject/");
                if (!folder.exists()) {
                    if (!folder.mkdir()) {
                        Log.e("ERROR", "Cannot create a directory!");
                    } else {
                        folder.mkdirs();
                    }
                }

                //File[] fileName = {new File(folder, "one.jpg"), new File(folder, "two.jpg")};


                for (DownLoadList i:mdataCollection)
                {
                    File fileName = new File(folder,i.getUid().toLowerCase()+".jpg");


                    if (!fileName.exists()) {
                        try {
                            fileName.createNewFile();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    else
                    {

                        try {
                            FileOutputStream outputStream = new FileOutputStream(String.valueOf(fileName));
                            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
                            outputStream.close();

                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }


                }


            }
        }).start();

    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable)
    {
        Log.e("PICASSO","FAILED"+errorDrawable.toString());

    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {

    }
};

What is probably causing this redundancy, and how to fix it?


Solution

  • Target is called for each image.

    Each image is getting written in cache under every name.

    First ar11.jpg is saved as ar11.jpg, ar12.jpg, ar13.jpg. Then same happens with ar12.jpg and ar13.jpg

    Try this code:

    private void downloadImage()
    {
        RealmResults<ARDatabase> results = mRealm.where(ARDatabase.class).findAll();
    
        for(ARDatabase x:results)
        {
            if(!x.getIsDownloaded())
            {
                mdataCollection.add(new DownLoadList(x.getUrlImg(),x.getUid()));
            }
        }
    
        for(DownLoadList i:mdataCollection)
        {
            Log.e("Link",""+i.getImageUrl());
            Picasso.with(getApplicationContext()).load(i.getImageUrl()).into(getTarget(i));
        }
    }
    
    private Target getTarget(DownLoadList downLoadList) {
        Target target = new Target() {
            @Override
            public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from)
            {
                Log.e("PICASSO","SUCCESSFUL");
    
                new Thread(new Runnable() {
                    @Override
                    public void run() {
    
                        File sd = getExternalCacheDir();
                        File folder = new File(sd, "/arproject/");
                        if (!folder.exists()) {
                            if (!folder.mkdir()) {
                                Log.e("ERROR", "Cannot create a directory!");
                            } else {
                                folder.mkdirs();
                            }
                        }
    
                        //File[] fileName = {new File(folder, "one.jpg"), new File(folder, "two.jpg")};
    
    
                        File fileName = new File(folder, downLoadList.getUid().toLowerCase()+".jpg");
    
    
                        if (!fileName.exists()) {
                            try {
                                fileName.createNewFile();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        else
                        {
    
                            try {
                                FileOutputStream outputStream = new FileOutputStream(String.valueOf(fileName));
                                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
                                outputStream.close();
    
                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
    
                    }
                }).start();
    
            }
    
            @Override
            public void onBitmapFailed(Drawable errorDrawable)
            {
                Log.e("PICASSO","FAILED"+errorDrawable.toString());
    
            }
    
            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {
    
            }
    
        }
        return target;
    }