Search code examples
android-studiouniversal-image-loaderandroid-viewholder

How can i clear an android viewholder cache when i close my activity (Images repeating)


I'm new on Android Studio, I showed a listview of images and text in my main activity, everything worked fine until I started to have performance issues, those were solved following this tutorial:

https://www.youtube.com/watch?v=cKUxiqNB5y0 (the app showed in the video is almost the same as mine)

My problem now is that when I create new objects that are added to the listview the images are duplicated when I update the app (I think that is a cache issue because I am using universal image loader).

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import java.util.List;

public class CharacterListAdapter extends ArrayAdapter<AnimeCharacter> {
    private static final String TAG = "AnimeCharacterAdapter";
    private Context context;
    private int mResource;

    static class ViewHolder {
        TextView character_name;
        TextView character_anime;
        ImageView img;
    }

    public CharacterListAdapter(@NonNull Context context, int resource, @NonNull List<AnimeCharacter> objects) {
        super(context, resource, objects);
        this.context = context;
        mResource = resource;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        setup_image_loader();

        String character_name = getItem(position).getCharacter_name();
        String character_anime = getItem(position).getCharacter_anime();
        String img_url = getItem(position).getCharacter_img();

        ViewHolder view_holder;
        view_holder = new ViewHolder();

        if (convertView == null) {
            LayoutInflater layout_inflater = LayoutInflater.from(context);
            convertView = layout_inflater.inflate(mResource, parent, false);
            view_holder.character_name = convertView.findViewById(R.id.txt_character_name);
            view_holder.character_anime = convertView.findViewById(R.id.txt_anime_name);
            view_holder.img = convertView.findViewById(R.id.character_img);


            convertView.setTag(view_holder);

        } else {
            view_holder = (ViewHolder) convertView.getTag();
        }

        int default_img = context.getResources().getIdentifier("@drawable/img_default", null, context.getPackageName());

        ImageLoader imageLoader = ImageLoader.getInstance();

        DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
                .cacheOnDisc(true).resetViewBeforeLoading(true)
                .showImageForEmptyUri(default_img)
                .showImageOnFail(default_img)
                .showImageOnLoading(default_img).build();

        imageLoader.displayImage(img_url, view_holder.img, options);

        view_holder.character_name.setText(character_name);
        view_holder.character_anime.setText(character_anime);



//        ImageLoader.getInstance().clearMemoryCache();
//        ImageLoader.getInstance().clearDiskCache();

        return convertView;
    }

    private void setup_image_loader() {
        // UNIVERSAL IMAGE LOADER SETUP
        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .cacheOnDisc(true).cacheInMemory(true)
                .imageScaleType(ImageScaleType.EXACTLY)
                .displayer(new FadeInBitmapDisplayer(300)).build();

        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                context)
                .defaultDisplayImageOptions(defaultOptions)
                .memoryCache(new WeakMemoryCache())
                .discCacheSize(100 * 1024 * 1024).build();


        ImageLoader.getInstance().init(config);
        // END - UNIVERSAL IMAGE LOADER SETUP
    }

}

I found other posts where the solution was clearing the cache with this lines of code:

ImageLoader.getInstance().clearMemoryCache();
ImageLoader.getInstance().clearDiskCache();

My problem is that i dont know how to override the method "onDestroy" inside the Adapter, in this post, they implented it in the MainActivity

android universal image loader clear cache

The last thing, when i unistall the app on my phone, and i rebuild it, the problem is gone (until i add another object to the listview)


Solution

  • I solved with this code:

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            trimCache(this);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    public static void trimCache(Context context) {
        try {
            File dir = context.getCacheDir();
            if (dir != null && dir.isDirectory()) {
                deleteDir(dir);
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
    
    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;
                }
            }
        }
    
        // The directory is now empty so delete it
        return dir.delete();
    }