Hot questions for Using Glide in caching

Question:

I do not quite understand how the recyclerView and glide work with regards to caching information and image data so I was wondering if anybody could help.

Currently I store meta-data about my images in the realtime database. The meta-data has enough information to be able to make a storage reference and pull the correct image from the database:

storageReference.child("users/uid/profile.png")

However, my question is regarding the firebaseUI element:

Glide.with(this)
    .using(new FirebaseImageLoader())
    .load(storageReference)
    .into(imageView);

So I add to images to my recyclerview as follows:

for (ProfileCard card : localDB.getAllCards()) {
   profileCards.add(1, card);
   adapter.notifyItemInserted(1);
}

Now everytime I leave this activity where the cards reside the activity is obviously destroyed. In the onCreate of the class the for loop is called again. So when I do adapter.notifyItemInserted(1); the adapter will be called and the glide function for adding the picture will be called again.

So my question is everytime I destroy and re-create the activity and then add the cards again when the glide method is called does it make a request to the storage bucket to download the image again? If not what happens? and if the images are stored in cache how big is this cache?

Any help is much appreciated


Answer:

Many of your answers about Glide can be answered if you read through the project wiki on GitHub.

When Glide fetches an image, it will be cached locally in memory and on disk. You can configure the sizes of these caches. Here's what the documentation has to say about the default disk cache size:

The internal cache factory places the disk cache in your application's internal cache directory and sets a maximum size of 250MB.

And for the memory cache:

Default sizes are determined by the MemorySizeCalculator class. The MemorySizeCalculator class takes into account the screen size available memory of a given device to come up with reasonable default sizes.

It's expected that things will be built up and torn down repeatedly. That's why these caches exist.

Question:

I used glide 4.4.0 version.

I reviewed this link: How to load image through byte array using Glide?

But my question is different. I would like to directly byte array into imageView and it is possible Glide v4

https://github.com/bumptech/glide/blob/0cffd1da977e9ca334032ebc1d798213a177aab7/library/src/main/java/com/bumptech/glide/ModelTypes.java

 @NonNull
 @CheckResult
 T load(@Nullable byte[] model)

My question is how its caching image. It is provide that image loading is faster.

Please help me.

private void loadImageBytesWithGlide(byte[] imageBytes, final ImageView imageView) {

        glideRequests
                .load(imageBytes)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .transition(withCrossFade())
                .into(imageView);

    }

Answer:

Create Image In sdcard from Base 64 string, then use Glide to loa image from path.

 if (theCaptchaBase64 != null) {
            byte[] image_data_bytes = Base64.decode(theCaptchaBase64, Base64.NO_WRAP);
            String Image_Data_str = null;
            try {
                Image_Data_str = new String(image_data_bytes, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            String imageFileExt = ".jpg";
            if (Image_Data_str != null && Image_Data_str.contains("png")) {
                imageFileExt = ".png";
            }


            long msTime = System.currentTimeMillis();
            Date dt = new Date(msTime);
            String format = "yyMMddHHmmssSSS";
            SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
            String captchaFileName = String.format("Captcha" + "_%s", sdf.format(dt).toString());
            //String captchaFileName = "Captcha";
            captchaFileName = captchaFileName + imageFileExt;

            String imageSaveFolderPath = TempFolderPath + "/" + captchaFileName;

            String imgPath = writeImageBytesOnSdCard(this, imageSaveFolderPath, Image_Data_str);

            loadImageWithGlide(this,ImageViiew,imgPath);
        }


         public static void loadImageWithGlide(Context theCtx, ImageView theImageView, String theUrl) {
        // 20170401 JK
        // skipMemoryCache, because it load the same image because URL not change.
        Glide.with(theCtx)
                .load(theUrl)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .skipMemoryCache(true)
                .into(theImageView);

        //Glide.with(mContext).load(imagePath).into(myHolder.mImageViewUserImage);
    }


        public static String writeImageBytesOnSdCard(Activity theActivity, String theCustomImagePath, String theCustomImageData) {
        String imagePath = theCustomImagePath;
        String temp[] = theCustomImageData.split("\\,");
        if (temp[0].contains("data:image/png")) {
            imagePath = getImagePath(imagePath, "png");
        } else {
            imagePath = getImagePath(imagePath, "jpg");
        }
        byte[] data = null;
        try {
            //data=myImageData1.getBytes("UTF-8");
            data = Base64.decode(temp[1], Base64.DEFAULT);
            FileOutputStream outputStream = null;
            outputStream = new FileOutputStream(new File(imagePath), false);
            InputStream in = new ByteArrayInputStream(data);

            OutputStream out = new BufferedOutputStream(outputStream);
            byte[] loginBuffer = new byte[1024];
            int byteRead = 0;
            while ((byteRead = in.read(loginBuffer)) != -1) {
                out.write(loginBuffer, 0, byteRead);
            }
            out.close();
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // code for sending a notification to the media scanner
            updateMedia(theActivity, imagePath);

        } catch (FileNotFoundException e) {
            imagePath = "";
            e.printStackTrace();
        } catch (IOException e) {
            imagePath = "";
            e.printStackTrace();
        }
        return imagePath;
    }

    public static String getImagePath(String theExportImagePath, String theRequiredExt) {
        File f = new File(theExportImagePath);
        String fileName = f.getName();

        String parent = f.getParent();
        String filename_Without_Ext = fileName;

        int dotposition = fileName.lastIndexOf(".");

        if (dotposition != -1)
            filename_Without_Ext = fileName.substring(0, dotposition);

        return parent + "/" + filename_Without_Ext + "." + theRequiredExt;
    }

    public static void updateMedia(final Activity theActivity, String filepath) {
        MediaScannerConnection.scanFile(theActivity.getApplicationContext(), new String[]{filepath}, null, null);

    }

Question:

Hello guys I have a problem with RecyclerView I tried about something like chat. I have sometimes images and text something only text and something only images in one row in recyclerview.

Everything work good while not scrolling and rows falls out of memory.

when falls out of memory and I want show it again row shown only progressbar, glide not loading.

I use glide into ViewHolder I not doing anything other with image in viewholder only code which pasted in this Thread.

GlideApp.with(v).load(conv.getUrlFromServer()).diskCacheStrategy(DiskCacheStrategy.ALL).placeholder(R.mipmap.ic_launcher).centerCrop().listener(new RequestListener<Drawable>() {
                @Override
                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                    circleProgresBar.setVisibility(View.GONE);
                    pictureMsg.setVisibility(View.VISIBLE);
                    return false;
                }

                @Override
                public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                    pictureMsg.setVisibility(View.VISIBLE);
                    circleProgresBar.setVisibility(View.GONE);
                    return false;
                }
            }).into(pictureMsg);

my viewholders .XML

   <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">


    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/LineLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="0dp"
        android:layout_marginLeft="0dp"
        android:layout_marginRight="0dp"
        android:layout_marginTop="0dp"
        android:gravity="left">

        <android.support.v7.widget.CardView
            android:id="@+id/rowCard"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/card_Bottom"
            android:layout_marginRight="@dimen/card_Right"
            android:layout_marginTop="@dimen/card_Top"
            card_view:cardCornerRadius="20dp"
            card_view:cardElevation="5dp">

            <android.support.constraint.ConstraintLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                tools:layout_editor_absoluteX="0dp"
                tools:layout_editor_absoluteY="0dp">

                <TextView
                    android:id="@+id/text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="@dimen/text_End"
                    android:layout_marginStart="@dimen/textview_Start"
                    android:layout_marginTop="@dimen/textview_top"
                    android:gravity="left"
                    android:paddingRight="@dimen/textview_Right"
                    android:text="Kolo"
                    android:textColor="@color/black"
                    android:textSize="16sp"
                    card_view:layout_constraintBottom_toBottomOf="parent"
                    card_view:layout_constraintEnd_toEndOf="parent"
                    card_view:layout_constraintHorizontal_bias="0.0"
                    card_view:layout_constraintStart_toStartOf="parent"
                    card_view:layout_constraintTop_toTopOf="parent"
                    card_view:layout_constraintVertical_bias="0.0" />

                <FrameLayout
                    android:id="@+id/frameLayout"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    card_view:layout_constraintBottom_toBottomOf="parent"
                    card_view:layout_constraintEnd_toEndOf="parent"
                    card_view:layout_constraintHorizontal_bias="0.5"
                    card_view:layout_constraintStart_toStartOf="parent"
                    card_view:layout_constraintTop_toBottomOf="@+id/text"
                    card_view:layout_constraintVertical_bias="0.5">

                    <ImageView
                        android:id="@+id/pictureMsg"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginEnd="@dimen/text_End"
                        android:layout_marginStart="@dimen/textview_Start"
                        android:adjustViewBounds="false"
                        android:minHeight="0dp"
                        android:visibility="visible" />

                    <ProgressBar
                        android:id="@+id/circleProgresBar"
                        style="?android:attr/progressBarStyle"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:visibility="gone" />
                </FrameLayout>

            </android.support.constraint.ConstraintLayout>


        </android.support.v7.widget.CardView>


    </RelativeLayout>

</LinearLayout>

I tried this

    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setDrawingCacheEnabled(true);
    mRecyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);

but unsuccesfull when increase caching number it was logically helped for little scrolling but it's not a solution. and it's use a lot of memory.

it's all what I thing you needed for explain my problem. I Paste Screens for better explain.

this is after launch screen Scrolling up for fall of memory. and go back on the bottom it's permanently loading (glide doing nothing in background)

Sorry for graphics :D

Thanks for any advice.

===================================Added info===============================

Here Is my onBindMethod for me is setDataOnView because have MyGeneriViewholder Implemented

@Override
    public void setDataOnView(int position, final RealmModel data) {
        RealmModelMessage conv = (RealmModelMessage) data;
        if (!conv.isStatus()) {
            mRow.setAlpha(0.5f);
        } else {
            mRow.setAlpha(1f);
        }
        RelativeLayout.LayoutParams llpCard;
        if (conv.getId_from() != mMyId) {
            mText.setGravity(Gravity.LEFT);
            mRow.setGravity(Gravity.LEFT);
         //   mText.setPadding(0, 0, mTextMargin_Right, 0);

            llpCard = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            llpCard.setMargins(0, mCardMargin_Top, mCardMargin_Right, mCardMargin_Bottom); // llp.setMargins(left, top, right, bottom)
            mCardView.setLayoutParams(llpCard);
            mCardView.setPadding(mTextMargin_Start, mTextMargin_Top, mTextMargin_End, mTextMargin_Bottom); // llp.setMargins(left, top, right, bottom);
            mCardView.setCardBackgroundColor(Color.argb(225,0,238,238));

            if (!String.valueOf(conv.getUrlFromServer()).equals("")){
                pictureMsg.setVisibility(View.VISIBLE);
                GlideApp.with(v).load(conv.getUrlFromServer()).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).placeholder(R.mipmap.ic_launcher).fitCenter().listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        circleProgresBar.setVisibility(View.GONE);
                  //      Toast.makeText(v.getContext(), "Chyba obrázku", Toast.LENGTH_SHORT).show();
                        pictureMsg.setBackground(v.getContext().getResources().getDrawable(R.mipmap.ic_launcher));
                        pictureMsg.setVisibility(View.VISIBLE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        pictureMsg.setVisibility(View.VISIBLE);
                        circleProgresBar.setVisibility(View.GONE);
                        return false;
                    }
                }).into(pictureMsg);} else {
                pictureMsg.setVisibility(View.GONE);
            }

        } else {
            mText.setGravity(Gravity.RIGHT);
            mRow.setGravity(Gravity.RIGHT);

            llpCard = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            llpCard.setMargins(mCardMargin_Right, mCardMargin_Top, 0, mCardMargin_Bottom); // llp.setMargins(left, top, right, bottom)
            mCardView.setLayoutParams(llpCard);
            mCardView.setPadding(0, mTextMargin_Top, mTextMargin_Start, mTextMargin_Bottom); // llp.setMargins(left, top, right, bottom)
            mCardView.setCardBackgroundColor(Color.argb(225,238,238,0));

            if (!String.valueOf(conv.getUrlFromServer()).equals("")){
                circleProgresBar.setVisibility(View.VISIBLE);
               // pictureMsg.setVisibility(View.VISIBLE);
              //GlideApp.with(v).load(conv.getUrlFromServer()).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).placeholder(R.mipmap.ic_launcher).centerCrop().into(pictureMsg);
               GlideApp.with(v).load(conv.getUrlFromServer()).diskCacheStrategy(DiskCacheStrategy.ALL).placeholder(R.mipmap.ic_launcher).centerCrop().listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        circleProgresBar.setVisibility(View.GONE);
                        Toast.makeText(v.getContext(), "Chyba obrázku", Toast.LENGTH_SHORT).show();
                        pictureMsg.setVisibility(View.VISIBLE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        pictureMsg.setVisibility(View.VISIBLE);
                        circleProgresBar.setVisibility(View.GONE);
                        return false;
                    }
                }).into(pictureMsg);

                /*        Drawable drawable=pictureMsg.getDrawable();
                double width =pictureMsg.getDrawable().getIntrinsicHeight();
                double heigh =pictureMsg.getDrawable().getIntrinsicWidth();
                double widthInScreen= v.getContext().getResources().getDimension(R.dimen.minWidth_Image150dp);
                double constant= widthInScreen/width;
                double newWidth= width*constant;
                double newHeigh= heigh*constant;
                FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams((int) newWidth,(int) newHeigh);
                pictureMsg.setLayoutParams(layoutParams);
                */
            } else {
                pictureMsg.setVisibility(View.GONE);
            }

        }

        mText.setText(conv.getText());

}

Answer:

I solve my problem with .override(int)

like this dimen between () is width and heigh.

GlideApp.with(v).load(conv.getUrlFromServer()).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).override((int) v.getContext().getResources().getDimension(R.dimen.minWidth_Image150dp), v.getContext().getResources().getDimension(R.dimen.minWidth_Image150dp)).placeholder(R.mipmap.ic_launcher).centerCrop().listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        circleProgresBar.setVisibility(View.GONE);
                        Toast.makeText(v.getContext(), "Chyba obrázku", Toast.LENGTH_SHORT).show();
                        pictureMsg.setVisibility(View.VISIBLE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        pictureMsg.setVisibility(View.VISIBLE);
                        circleProgresBar.setVisibility(View.GONE);
                        return false;
                    }
                }).into(pictureMsg);

I don't know what this work good.

Question:

i am retrieving images URL using volley from MySQL Database , when am online i have no problem , but i need to make it offline too so am using SQLite to store data, but when the image loads it displays the first picture saved in cache , and i have no idea how to resolve this.

I was using BLOB before but the application became too slow after adding lot of data.

Thanks for help.


Answer:

Use signature

   Glide.with(this)
        .load(url)
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .signature(new StringSignature(UUID.randomUUID().toString())) //use this 
        .into(imgView);

Question:

Is there any way to delete the cache of the app at exit as using Glide to load images in recylerview from different fragments and activities is generating a huge amount of cache to the App.(don,t want to use disk cache strategies of glide as caches are required during runtime)


Answer:

If you are looking for delete cache of your own application then simply delete your cache directory and it's all done!

public static void deleteCache(Context context) {
    try {
        File dir = context.getCacheDir();
        deleteDir(dir);
    } catch (Exception e) { e.printStackTrace();}
}


public static boolean deleteDir(File dir) {
    if (dir != null && dir.isDirectory()) {
        String[] children = dir.list();
        for (int i = 0; i < children.length; i++) {
            boolean success = deleteDir(new File(dir, children[i]));
            if (!success) {
                return false;
            }
        }
        return dir.delete();
    } else if(dir!= null && dir.isFile()) {
        return dir.delete();
    } else {
        return false;
    }
}

Question:

I am using Glide image library with a Recycler View to load hundreds of images as the user scrolls down from website URL's.The problem is that glide is caching all these images thus increasing app size to a lot of un-needed disk space. Thus I want to disable cache.Unfortunately I am not getting an exact method to do so yet.

I tried using

Glide.with(context) .load(itemList.get(position) .skipMemoryCache(true) .getPhoto()).into(holder.Photo);

where itemList.get(position) contains URL but this is not being accepted with a not defined error in android studio.

What would be a good solution to this problem. Any other libraries which can help for loading images from URL is also appriciated.

Edit: .diskCacheStratergy, .skipMemoryCache and .signature dosn't seem to work inside Adapters where I am loading all the images

Edit 2:There was a problem in the build I think .diskCacheStratergy and .skipMemoryCache options came once I refreshed and synced my app.gradle again


Answer:

Try Using .diskCacheStrategy( DiskCacheStrategy.NONE )

   Glide  
        .with( context )
        .load( eatFoodyImages[0] )
        .diskCacheStrategy( DiskCacheStrategy.NONE )
        .skipMemoryCache( true )
        .into( imageViewInternet );

for more please check this link https://futurestud.io/tutorials/glide-caching-basics