0

I have made an application in which there is gridview and when we we select any thumbnail on it we see the full size image in viewpager. But when i click on thumbnail and view image for many times i get out of memory in android.I have searched a lot and found one solution to use picasso instead of imageloader but i can not use picasso .I have do it with imageloader only. Can anyone please tell me the exact configuration and options for imageloader so that i do not get out of memory????

Please help i have tried many configuration changes.

    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);

        }
  • This has been asked (and answered) [several](http://stackoverflow.com/questions/10436927/out-of-memory-error-with-loading-image) [times](http://stackoverflow.com/questions/541966/lazy-load-of-images-in-listview) already, do a search and you will find your answer. – Sebastian Aug 04 '15 at 06:40
  • I am using imageloader not bitmap to load images from url so these two links given by you can not be udsed – vijay kumar Aug 04 '15 at 06:42
  • If you want an answer, first you should show what you have done already. Include some code. StackOverflow is not for people writing code for others, but to ask for help after you have tried and could not find a solution. – Sebastian Aug 04 '15 at 06:43
  • this is my viewpager adapter. Here i am loading images from url but when in load tenth image in pageradapter i get oom – vijay kumar Aug 04 '15 at 06:47

3 Answers3

2

ImageLoader isn't directly your issue; The main problem you have is mis-management of bitmaps.

Firstly, you shouldn't be loading brand new bitmap objects for each instance of an image you need. This leads to many allocations in your bitmap heap, and lots of memory blocks taken up. As described in Re-using bitmaps You can load new bitmaps into the memory space of old bitmaps which might not be used any longer. You can couple this with an LRUCache so you know what images you don't need any more, and you can re-use their memory. Think of this process much akin to objectpools.

Secondly, Make sure that you're using the right image pixel formats. As described in Smaller Pixel Formats using the RGB_565 format will save you about 50% per pixel in terms of memory, which is perfect for opaque images loaded from JPG files.

Thirdly, take a hard look through your memory allocations to ensure that your bitmap objects are being properly freed. If you're not releasing them properly, you're creating a new memory leak that takes up memory, and doesn't release it back to the application.

Addressing all these issues is critical for applications with high bitmap loads, in order to avoid out-of-memory problems.

Colt McAnlis
  • 3,846
  • 3
  • 18
  • 19
1

The important thing to consider is that images generally get decoded using 3 or 4 bytes per pixel. So a 5Mpx image will require 20Mb, often more than what the OS will allow for your app on some phones. You have to modify the options while loading the image so that it's scaled down when decoded.

Have you read this? There are plenty of suggestions for dealing with Out Of Memory errors.

If you often got OutOfMemoryError in your app using Universal Image Loader then:

  • Disable caching in memory. If OOM is still occurs then it seems your app has a memory leak. Use MemoryAnalyzer to detect it. Otherwise try the following steps (all of them or several):

  • Reduce thread pool size in configuration (.threadPoolSize(...)). 1 - 5 is recommended.

  • Use .bitmapConfig(Bitmap.Config.RGB_565) in display options. Bitmaps in RGB_565 consume 2 times less memory than in ARGB_8888.

  • Use .imageScaleType(ImageScaleType.EXACTLY)

  • Use .diskCacheExtraOptions(480, 320, null) in configuration

Community
  • 1
  • 1
Sebastian
  • 1,076
  • 9
  • 24
  • using these configuration i am getting out of memory after loading 25-26 images – vijay kumar Aug 04 '15 at 07:29
  • If you want to load concurrently 25 images full size, I doubt any phone memory will be enough. Most of the time one is enough the blow up the jvm. If you want to display them in a gallery view, they you will have to recycle and reload images when they are out of view. If there is not enough memory... then there is not enough memory, you will have to load less images at the same time. – Sebastian Aug 04 '15 at 07:49
  • i was using imageloader.clearmemorycache() on loading complete but still it is caching iamge – vijay kumar Aug 04 '15 at 07:53
0

I don't believe that it will solve your problem, but you should initiate ImageLoader in the method onCreate from your application (Create a class which extends Application and put the information in the manifest).

You could also show us a sample of the pictures you try to load, use a MemoryAnalyzer to find what takes that much memory and of course follow the recommended options in that case (disable cache, the imageScaleType... As said before)

leb1755
  • 1,386
  • 2
  • 14
  • 29