我如何在关闭 activity 时清除 android viewholder 缓存(图像重复)
How can i clear an android viewholder cache when i close my activity (Images repeating)
我是 Android Studio 的新手,我在我的主 activity 中显示了图像和文本的列表视图,一切正常,直到我开始遇到性能问题,这些问题在这之后得到解决教程:
https://www.youtube.com/watch?v=cKUxiqNB5y0(视频里的app和我的差不多)
我现在的问题是,当我创建添加到列表视图的新对象时,更新应用程序时图像会重复(我认为这是一个缓存问题,因为我使用的是通用图像加载器)。
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
}
}
我发现其他 post 的解决方案是使用以下代码行清除缓存:
ImageLoader.getInstance().clearMemoryCache();
ImageLoader.getInstance().clearDiskCache();
我的问题是我不知道如何覆盖 Adapter 中的方法 "onDestroy",在这个 post 中,他们在 MainActivity
中实现了它
最后一件事,当我在我的 phone 上卸载应用程序并重建它时,问题就消失了(直到我将另一个对象添加到列表视图)
我用这段代码解决了:
@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();
}
我是 Android Studio 的新手,我在我的主 activity 中显示了图像和文本的列表视图,一切正常,直到我开始遇到性能问题,这些问题在这之后得到解决教程:
https://www.youtube.com/watch?v=cKUxiqNB5y0(视频里的app和我的差不多)
我现在的问题是,当我创建添加到列表视图的新对象时,更新应用程序时图像会重复(我认为这是一个缓存问题,因为我使用的是通用图像加载器)。
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
}
}
我发现其他 post 的解决方案是使用以下代码行清除缓存:
ImageLoader.getInstance().clearMemoryCache();
ImageLoader.getInstance().clearDiskCache();
我的问题是我不知道如何覆盖 Adapter 中的方法 "onDestroy",在这个 post 中,他们在 MainActivity
中实现了它最后一件事,当我在我的 phone 上卸载应用程序并重建它时,问题就消失了(直到我将另一个对象添加到列表视图)
我用这段代码解决了:
@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();
}