我已经创建了一个有gridview的应用程序,当我们选择任何缩略图时,我们会在viewpager中看到完整大小的图像。但是当我点击缩略图并多次查看图像时,我在android中没有内存。我搜索了很多,发现一个解决方案使用毕加索代替图像加载器,但我不能使用毕加索。我只使用了imageloader。任何人都可以告诉我imageloader的确切配置和选项,以便我不会失去内存????
请帮助我尝试了很多配置更改。
public class ImagePagerAdapter extends PagerAdapter {
LayoutInflater inflater;
PhotoViewAttacher attacher;
PhotoViewAttacher pic;
private DisplayImageOptions options;
List<Image> IMAGES_LIST = AppController.getInstance().getPrefManger()
.getImages();
public ImagePagerAdapter(Context context) {
inflater = LayoutInflater.from(context);
options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.cacheOnDisc()
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.build();
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
final View imageLayout = inflater.inflate(
R.layout.item_pager_image, container, false);
assert imageLayout != null;
pos = position;
imageView = (TouchImageView) imageLayout.findViewById(R.id.image);
imageView.setTag(position);
imageView.setOnDoubleTapListener(new OnDoubleTapListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// TODO Auto-generated method stub
try
{
timer.cancel();
}
catch(Exception ex){}
if(IMAGES_LIST.get(position).getType().equalsIgnoreCase("image"))
{
mHandler.removeCallbacks(r);
share.setVisibility(View.VISIBLE);
play.setVisibility(View.VISIBLE);
done.setVisibility(View.VISIBLE);
if (!isCopyImage.equals("yes")) {
gimmy.setVisibility(View.VISIBLE);
}
comment.setVisibility(View.VISIBLE);
count.setVisibility(View.VISIBLE);
caption.setVisibility(View.VISIBLE);
mHandler.postDelayed(r, 5 * 1000);
}
else{
mHandler.removeCallbacks(r);
done.setVisibility(View.VISIBLE);
mHandler.postDelayed(r, 5 * 1000);
}
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
// TODO Auto-generated method stub
Log.i("hello", "");
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
});
try{
final ProgressBar spinner = (ProgressBar) imageLayout
.findViewById(R.id.loading);
final ImageView videoplay = (ImageView) imageLayout
.findViewById(R.id.play);
if(IMAGES_LIST.get(position).getType().equalsIgnoreCase("image"))
{
videoplay.setVisibility(View.INVISIBLE);
ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(container.getContext());
config.memoryCache(new WeakMemoryCache());
config.denyCacheImageMultipleSizesInMemory();
config.discCache(new UnlimitedDiskCache(container.getContext().getCacheDir()));
imageLoader=ImageLoader.getInstance();
imageLoader.init(config.build());
imageLoader.displayImage(
AppConst.BASE_IMAGE_URL
+ IMAGES_LIST.get(position).getFileName(),
imageView, options, new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
spinner.setVisibility(View.VISIBLE);
view.setVisibility(View.GONE);
}
@Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
String message = null;
switch (failReason.getType()) {
case IO_ERROR:
message = "Input/Output error";
break;
case DECODING_ERROR:
message = "Image can't be decoded";
break;
case NETWORK_DENIED:
message = "Downloads are denied";
break;
case OUT_OF_MEMORY:
message = "Out Of Memory error";
break;
case UNKNOWN:
message = "Unknown error";
break;
}
spinner.setVisibility(View.GONE);
}
@Override
public void onLoadingComplete(String imageUri,
View view, Bitmap loadedImage) {
spinner.setVisibility(View.GONE);
view.setVisibility(View.VISIBLE);
}
});
container.addView(imageLayout, 0);
}
答案 0 :(得分:2)
ImageLoader不是直接您的问题;您遇到的主要问题是错误管理位图。
首先,您不应为所需图像的每个实例加载全新的位图对象。这会导致位图堆中的许多分配,并占用大量内存块。如Re-using bitmaps中所述,您可以将新位图加载到旧位图的内存空间中,这些位图可能不再使用。您可以将其与LRUCache结合使用,这样您就可以了解不再需要的图像,并且可以重复使用它们的记忆。想想这个过程非常类似于objectpools。
其次,确保使用正确的图像像素格式。如Smaller Pixel Formats中所述,使用RGB_565格式将在内存方面为每个像素节省大约50%,这对于从JPG文件加载的不透明图像非常适合。
第三,仔细查看内存分配,确保正确释放位图对象。如果您没有正确发布它们,那么您将创建一个占用内存的new memory leak,而不会将其释放回应用程序。
解决所有这些问题对于具有高位图负载的应用程序至关重要,以避免出现内存不足问题。
答案 1 :(得分:1)
要考虑的重要事项是图像通常使用每像素3或4个字节进行解码。因此,5Mpx图像需要20Mb,通常比某些手机上的应用程序允许的操作系统更多。您必须在加载图像时修改选项,以便在解码时按比例缩小。
您是否阅读过this?处理Out Of Memory错误有很多建议。
如果您经常使用Universal Image Loader在您的应用中获得OutOfMemoryError:
禁用内存中的缓存。如果仍然出现OOM,那么您的应用程序似乎有内存泄漏。使用MemoryAnalyzer检测它。否则,请尝试以下步骤(所有这些步骤或几个步骤):
减少配置中的线程池大小(.threadPoolSize(...))。建议使用1 - 5.
在显示选项中使用.bitmapConfig(Bitmap.Config.RGB_565)。 RGB_565中的位图消耗的内存比ARGB_8888少2倍。
使用.imageScaleType(ImageScaleType.EXACTLY)
在配置中使用.diskCacheExtraOptions(480,320,null)
答案 2 :(得分:0)
我不相信它会解决您的问题,但您应该从应用程序的onCreate方法中启动ImageLoader(创建一个扩展Application并将信息放入清单中的类)。
您还可以向我们展示您尝试加载的图片示例,使用MemoryAnalyzer查找占用大量内存的内容,当然还要遵循建议的选项(禁用缓存,imageScaleType ......如前所述) )