2

I keep getting this error when I run my app. The app will compile fine and once I start interacting with it (ImageSlider) sometimes it breaks and comes up with that message.

LogCat

    02-18 12:25:05.426: E/AndroidRuntime(4545): FATAL EXCEPTION: main
02-18 12:25:05.426: E/AndroidRuntime(4545): java.lang.OutOfMemoryError
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at com.oneplc.viessmannapp.imageslider.adapter.FullScreenImageAdapter.instantiateItem(FullScreenImageAdapter.java:59)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:832)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.support.v4.view.ViewPager.populate(ViewPager.java:1016)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.support.v4.view.ViewPager$3.run(ViewPager.java:244)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.support.v4.view.ViewPager.completeScroll(ViewPager.java:1761)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.support.v4.view.ViewPager.onInterceptTouchEvent(ViewPager.java:1894)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1629)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1684)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1684)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1684)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1684)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1917)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1371)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.app.Activity.dispatchTouchEvent(Activity.java:2364)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1865)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.View.dispatchPointerEvent(View.java:5721)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2890)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2466)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2475)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.os.Looper.loop(Looper.java:137)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at android.app.ActivityThread.main(ActivityThread.java:4424)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at java.lang.reflect.Method.invokeNative(Native Method)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at java.lang.reflect.Method.invoke(Method.java:511)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
02-18 12:25:05.426: E/AndroidRuntime(4545):     at dalvik.system.NativeStart.main(Native Method)

THE CLASS RESPONSIBLE / FullScreenImageAdapter.java at line : 59

    public class FullScreenImageAdapter extends PagerAdapter {

    private Activity _activity;
    private ArrayList<String> _imagePaths;
    private LayoutInflater inflater;

    // constructor
    public FullScreenImageAdapter(Activity activity,
            ArrayList<String> imagePaths) {
        this._activity = activity;
        this._imagePaths = imagePaths;
    }

    @Override
    public int getCount() {
        return this._imagePaths.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == ((RelativeLayout) object);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        TouchImageView imgDisplay;
        Button btnClose;

        inflater = (LayoutInflater) _activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View viewLayout = inflater.inflate(R.layout.layout_fullscreen_image, container,
                false);

        imgDisplay = (TouchImageView) viewLayout.findViewById(R.id.imgDisplay);
        btnClose = (Button) viewLayout.findViewById(R.id.btnClose);

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        Bitmap bitmap = BitmapFactory.decodeFile(_imagePaths.get(position), options);
        imgDisplay.setImageBitmap(bitmap);

        // close button click event
        btnClose.setOnClickListener(new View.OnClickListener() {            
            @Override
            public void onClick(View v) {
                _activity.finish();
            }
        });

        ((ViewPager) container).addView(viewLayout);

        return viewLayout;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        ((ViewPager) container).removeView((RelativeLayout) object);

    }
}

COMMENTS

I saw some other threads but they where not helpfull, or at least not implementable on my case.

Any idea how can I tacle this issue?

8
  • 1
    you can use Universal imageLoader class..... Commented Feb 18, 2014 at 12:37
  • So is this implementing in full screen Activity??? I am right now implementing same thing and working fine for me. Commented Feb 18, 2014 at 12:43
  • Its very weird because wen I run this feature on its own, it works fine, but when I incorporate it in my app, i get the memory error.. Commented Feb 18, 2014 at 12:51
  • Ya because may be you are using high resolution images??And if this images fetch from server? Commented Feb 18, 2014 at 12:52
  • So have you got it now? Commented Feb 18, 2014 at 13:06

4 Answers 4

5

If Google docs didn't help (and they have some neat techniques), as a last resort you can try adding android:largeHeap="true" to the <application> tag in the AndroidManifest.xml. But really, last resort.

Sign up to request clarification or add additional context in comments.

Comments

2

You should look at this article on android dev site http://developer.android.com/training/displaying-bitmaps/index.html . You should load bitmap asynchronously, because you are decoding file and its expensive operation and you should also first load bitmap size and than scale it to real size of imageview

Comments

1

you should use this......

      @Override
    public Object instantiateItem(ViewGroup container, int position) {
        final TouchImageView imgDisplay;

        inflater = (LayoutInflater) _activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View viewLayout = inflater.inflate(
                R.layout.layout_fullscreen_image, container, false);

        imgDisplay = (TouchImageView) viewLayout
                .findViewById(R.id.imgDisplay);
        final ProgressBar spinner = (ProgressBar) viewLayout
                .findViewById(R.id.loading);
        // btnShare = (Button) viewLayout.findViewById(R.id.btnShare);

        imageLoader.displayImage(_imagePaths.get(position).get("url"),
                imgDisplay, options, new ImageLoadingListener() {
                    @Override
                    public void onLoadingStarted() {
                        spinner.setVisibility(View.VISIBLE);
                    }

                    @Override
                    public void onLoadingFailed(FailReason failReason) {
                        String message = null;
                        switch (failReason) {
                        case IO_ERROR:
                            message = "Input/Output error";
                            break;
                        case OUT_OF_MEMORY:
                            message = "Out Of Memory error";
                            break;
                        case UNKNOWN:
                            message = "Unknown error";
                            break;
                        }
                        Toast.makeText(FullScreenViewActivity.this,
                                message, Toast.LENGTH_SHORT).show();

                        spinner.setVisibility(View.GONE);
                        imgDisplay
                                .setImageResource(android.R.drawable.ic_delete);
                    }

                    @Override
                    public void onLoadingComplete(Bitmap loadedImage) {
                        spinner.setVisibility(View.GONE);
                        Animation anim = AnimationUtils
                                .loadAnimation(FullScreenViewActivity.this,
                                        R.anim.fade_in);
                        imgDisplay.setAnimation(anim);
                        anim.start();

                    }

                    @Override
                    public void onLoadingCancelled() {
                        // Do nothing
                    }
                });

        ((ViewPager) container).addView(viewLayout, 0);

        return viewLayout;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        ((ViewPager) container).removeView((FrameLayout) object);

    }
}

Add this code on onCreate() method..

      private DisplayImageOptions options;

      options = new DisplayImageOptions.Builder()
            .showImageForEmptyUri(R.drawable.ic_launcher).cacheOnDisc()
            .imageScaleType(ImageScaleType.IN_SAMPLE_INT).build();

Add universal-image-loader-1.6.1-with-src.jar jar file to your libs folder.

UPDATE:

 private DisplayImageOptions options;
 public FullScreenImageAdapter(Activity activity,
        ArrayList<String> imagePaths) {
    this._activity = activity;
    this._imagePaths = imagePaths;
    options = new DisplayImageOptions.Builder()
            .showImageForEmptyUri(R.drawable.ic_launcher).cacheOnDisc()
            .imageScaleType(ImageScaleType.IN_SAMPLE_INT).build();
 }

7 Comments

I will try it now Piyush!
Piyush, my class extends adapter and is not an activity, so that means that I do not have an onCreate method.
you can also add it on your Adapter class Constructor.
Ok I have completed the class but I get some errors :
Ok do one thing remove from that constructor. Have you make different class of adapter? If you had, then just make that class inside the activity from which your adapter class being called. I am going now. So if still u have query leave it here.
|
0

if anyone trying to get images from sqlite and getting outOfMemory error try following :

cursor = adapter.getAllrecords(); //get your table records in cursor

//moving to the current position in cursor 
cursor.moveToPosition(position);

byte [] image = cursor.getBlob(cursor.getColumnIndex("image"));

 BitmapFactory.Options options = new  BitmapFactory.Options();
 options.inJustDecodeBounds = true;
 bitmapImage = BitmapFactory.decodeByteArray(image, 0, image.length, options);
 imageView.setImageBitmap(decodeSampledBitmapFromResource(80, 80));//pass height and             
                                                      //width as per your requirement 



public  int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int     
reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
             while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }
        public  Bitmap decodeSampledBitmapFromResource(int reqWidth, int reqHeight) {

            // First decode with inJustDecodeBounds=true 
                to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeByteArray(image, 0, image.length, options);

            // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

            // Decode bitmap with inSampleSize set
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeByteArray(image, 0, image.length, options);
        }

this code worked for me..however according to developer guideliness we should handle image related task using AsyncTask...we should not run it on UI thread.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.