2

have to load all SDcard images into staggered view..when i set count 100 it shows that images in staggered view but for many no of images (eg.700/800) I am used AsyncTask but it shows doinbackground error please help me to out this.

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity
 {
  private StaggeredGridLayoutManager staggeredGridLayoutManager;
  MyAdapter myAdapter;
  List<ItemData> grid_view_item = new ArrayList<>();
   @Override
   protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    recyclerView.setHasFixedSize(true);

 staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
 recyclerView.setLayoutManager(staggeredGridLayoutManager);
            //call the LoadImage
            new LoadImage().execute();
            myAdapter = new MyAdapter(MainActivity.this, grid_view_item);
            recyclerView.setAdapter(myAdapter);

       }

this is AsncTask class.

class LoadImage extends AsyncTask<Void,Void,Void>
        {
            private int count;
            private Bitmap[] thumbnails;
            private boolean[] thumbnailsselection;
            private String[] arrPath;

            @Override
            protected Void doInBackground(Void... params)
            {
                //load gallery iamges
                final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID};
                final String orderBy = MediaStore.Images.Media._ID;
                Cursor imagecursor = managedQuery(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null,
                        null, orderBy);
                int image_column_index = imagecursor.getColumnIndex(MediaStore.Images.Media._ID);
                Log.e("COUNT ", "" + image_column_index);
                this.count = imagecursor.getCount();
                Log.e("COUNT ", "" + count);
                this.thumbnails = new Bitmap[this.count];
                Log.e("COUNT ", "" + thumbnails);
                this.arrPath = new String[this.count];
                Log.e("COUNT ", "" + arrPath);
                this.thumbnailsselection = new boolean[this.count];
                Log.e("COUNT ", "" + thumbnailsselection);
                for (int i = 0; i < this.count; i++) {
                    imagecursor.moveToPosition(i);
                    int id = imagecursor.getInt(image_column_index);
                    int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA);
                    thumbnails[i] = MediaStore.Images.Thumbnails.getThumbnail(
                            getApplicationContext().getContentResolver(), id,
                            MediaStore.Images.Thumbnails.MINI_KIND, null);
                    arrPath[i] = imagecursor.getString(dataColumnIndex);
                    grid_view_item.add(new ItemData(thumbnails[i]));
                }

                return null;
            }
        }

this is Adapter class.

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>
{
            private List<ItemData> itemsData;
            private Context context;

    public MyAdapter(Context context, List<ItemData> itemsData)
    {
                this.itemsData = itemsData;
                this.context = context;
    }

    @Override
            public int getItemCount() {
                return this.itemsData.size();
            }

            @Override
            public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                           int viewType) {
                // create a new view
                View itemLayoutView = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.staggered_view_image, null);

                // create ViewHolder

                ViewHolder viewHolder = new ViewHolder(itemLayoutView);
                return viewHolder;
            }

            // Replace the contents of a view (invoked by the layout manager)
            @Override
            public void onBindViewHolder(ViewHolder viewHolder, final int position) {

                viewHolder.img.setImageBitmap(itemsData.get(position).getImage());

            }


            // inner class to hold a reference to each item of RecyclerView
            public class ViewHolder extends RecyclerView.ViewHolder {
                public ImageView img;

                public ViewHolder(View itemLayoutView) {
                    super(itemLayoutView);
                    img = (ImageView) itemLayoutView.findViewById(R.id.gallery_photo);
                }
            }
}
}

LogCat.

1
12-30 08:49:50.329 2902-2935/com.staggeredgridview E/COUNT: 775
12-30 08:49:50.329 2902-2935/com.staggeredgridview E/COUNT: [Landroid.graphics.Bitmap;@40513478
12-30 08:49:50.329 2902-2935/com.staggeredgridview E/COUNT: [Ljava.lang.String;@405187f8
12-30 08:49:50.329 2902-2935/com.staggeredgridview E/COUNT: [Z@4053aa88
12-30 08:50:24.319 2902-2935/com.staggeredgridview E/dalvikvm-heap: 153600-byte external allocation too large for this process.
12-30 08:50:24.369 2902-2935/com.staggeredgridview E/GraphicsJNI: VM won't let us allocate 153600 bytes
12-30 08:50:24.369 2902-2935/com.staggeredgridview D/skia: libjpeg error 105 <  Ss=%d, Se=%d, Ah=%d, Al=%d> from allocPixelRef [320 240]
12-30 08:50:24.369 2902-2935/com.staggeredgridview D/skia: --- decoder->decode returned false
12-30 08:50:24.369 2902-2935/com.staggeredgridview E/MediaStore: failed to allocate memory for thumbnail content://media/external/images/thumbnails/615; java.lang.OutOfMemoryError: bitmap size exceeds VM budget
12-30 08:50:24.539 2902-2935/com.staggeredgridview E/dalvikvm-heap: 153600-byte external allocation too large for this process.
12-30 08:50:24.589 2902-2935/com.staggeredgridview E/GraphicsJNI: VM won't let us allocate 153600 bytes
12-30 08:50:24.589 2902-2935/com.staggeredgridview D/skia: libjpeg error 105 <  Ss=%d, Se=%d, Ah=%d, Al=%d> from allocPixelRef [320 240]
12-30 08:50:24.589 2902-2935/com.staggeredgridview D/skia: --- decoder->decode returned false
12-30 08:50:24.589 2902-2935/com.staggeredgridview E/MediaStore: failed to allocate memory for thumbnail content://media/external/images/thumbnails/615; java.lang.OutOfMemoryError: bitmap size exceeds VM budget
12-30 08:50:24.599 2902-2935/com.staggeredgridview V/MediaStore: Create the thumbnail in memory: origId=639, kind=1, isVideo=false
12-30 08:50:24.749 2902-2935/com.staggeredgridview E/dalvikvm-heap: 307200-byte external allocation too large for this process.
12-30 08:50:24.799 2902-2935/com.staggeredgridview E/GraphicsJNI: VM won't let us allocate 307200 bytes
12-30 08:50:24.799 2902-2935/com.staggeredgridview D/skia: libjpeg error 105 <  Ss=%d, Se=%d, Ah=%d, Al=%d> from allocPixelRef [320 240]
12-30 08:50:24.799 2902-2935/com.staggeredgridview D/skia: --- decoder->decode returned false
12-30 08:50:24.809 2902-2935/com.staggeredgridview W/dalvikvm: threadid=9: thread exiting with uncaught exception (group=0x40018578)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime: java.lang.RuntimeException: An error occured while executing doInBackground()
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at android.os.AsyncTask$3.done(AsyncTask.java:200)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.lang.Thread.run(Thread.java:1019)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:508)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at android.media.ThumbnailUtils.createThumbnailFromEXIF(ThumbnailUtils.java:489)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at android.media.ThumbnailUtils.createImageThumbnail(ThumbnailUtils.java:102)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at android.provider.MediaStore$InternalThumbnails.getThumbnail(MediaStore.java:455)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at android.provider.MediaStore$Images$Thumbnails.getThumbnail(MediaStore.java:791)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at com.staggeredgridview.MainActivity$LoadImage.doInBackground(MainActivity.java:73)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at com.staggeredgridview.MainActivity$LoadImage.doInBackground(MainActivity.java:42)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at android.os.AsyncTask$2.call(AsyncTask.java:185)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:     at java.lang.Thread.run(Thread.java:1019) 
OneCricketeer
  • 126,858
  • 14
  • 92
  • 185
vyas dipak
  • 69
  • 2
  • 12

2 Answers2

1

As well as I commented, you are getting error because the android system has some limitation to provide memory for application. If you want more memory than the allocated you have set largeHeap as true in manifest file. So that OS will allocate more memory as need. But this is not a best practise always. If you can reduce the memory consumption in anyway, that is thd best option. Or it will kill other application that are running in background. So your manifest will be like as follows

    <application
            android:icon="@mipmap/ic_launcher"
            android:largeHeap="true"
            android:theme="@style/AppTheme" >
            <activity
              .....
              ....../>
              ....
              ...
<application/>
droidev
  • 6,829
  • 9
  • 57
  • 85
0

for solve this issue I added android:largeHeap="true" in Android Manifest file in Application tag..it solve the problem but application require more heap memory..might it affect the other application and second thing it takes more time to load the images

this is the Android Manifest file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.staggeredgridview" >
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:largeHeap="true"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

this is the final code ..its works fine..

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {
    private int count;
    private Bitmap[] thumbnails;
    private boolean[] thumbnailsselection;
    private String[] arrPath;
    private StaggeredGridLayoutManager staggeredGridLayoutManager;
    MyAdapter myAdapter;
    List<ItemData> grid_view_item = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);


        staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(staggeredGridLayoutManager);
        myAdapter = new MyAdapter(MainActivity.this, grid_view_item);
        recyclerView.setAdapter(myAdapter);


        //load gallery iamges
        final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID};
        final String orderBy = MediaStore.Images.Media._ID;
        Cursor imagecursor = managedQuery(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null,
                null, orderBy);
        int image_column_index = imagecursor.getColumnIndex(MediaStore.Images.Media._ID);
        Log.e("COUNT ", "" + image_column_index);
        this.count = imagecursor.getCount();
        Log.e("COUNT ", "" + count);
        this.thumbnails = new Bitmap[this.count];
        Log.e("COUNT ", "" + thumbnails);
        this.arrPath = new String[this.count];
        Log.e("COUNT ", "" + arrPath);
        this.thumbnailsselection = new boolean[this.count];
        Log.e("COUNT ", "" + thumbnailsselection);
        for (int i = 0; i < this.count; i++) {
            imagecursor.moveToPosition(i);
            int id = imagecursor.getInt(image_column_index);
            int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA);
            thumbnails[i] = MediaStore.Images.Thumbnails.getThumbnail(
                    getApplicationContext().getContentResolver(), id,
                    MediaStore.Images.Thumbnails.MINI_KIND, null);
            arrPath[i] = imagecursor.getString(dataColumnIndex);
            grid_view_item.add(new ItemData(thumbnails[i]));
        }
    }

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
        private List<ItemData> itemsData;
        private Context context;

        public MyAdapter(Context context, List<ItemData> itemsData) {
            this.itemsData = itemsData;
            this.context = context;
        }

        @Override
        public int getItemCount() {
            return this.itemsData.size();
        }

        @Override
        public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                       int viewType) {
            // create a new view
            View itemLayoutView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.staggered_view_image, null);

            // create ViewHolder

            ViewHolder viewHolder = new ViewHolder(itemLayoutView);
            return viewHolder;
        }

        // Replace the contents of a view (invoked by the layout manager)
        @Override
        public void onBindViewHolder(ViewHolder viewHolder, final int position) {

            viewHolder.img.setImageBitmap(itemsData.get(position).getImage());

        }


        // inner class to hold a reference to each item of RecyclerView
        public class ViewHolder extends RecyclerView.ViewHolder {
            public ImageView img;

            public ViewHolder(View itemLayoutView) {
                super(itemLayoutView);
                img = (ImageView) itemLayoutView.findViewById(R.id.gallery_photo);
            }
        }
    }
}
vyas dipak
  • 69
  • 2
  • 12