0

I've an application to store name and image in database.Then I print name of images on listview.But just Im able to see first three elements from database..It shows me Window is full error.No problem on database,I checked database via sqlitebrowser and all elements are exist there.Probably there's problem on my arrayadapter.What's problem?Also images are small 30kb. Error when I try to see all images on ListView

Error

W/CursorWindow: Window is full: requested allocation 5397663 bytes, free space 1143664 bytes, window size 2097152 bytes
W/CursorWindow: Window is full: requested allocation 5397663 bytes, free space 2023760 bytes, window size 2097152 bytes
Window is full: requested allocation 5397663 bytes, free space 2096700 bytes, window size 2097152 bytes
E/SQLiteCursor: onMove() return false. RequiredPos: 3 WindowStartPos: 3 WindowRowCount: 0(original count of query: 6) 

OnCreate Method

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView listView = (ListView) findViewById(R.id.listView);

        final ArrayList<String> artName = new ArrayList<String>();
        artImage = new ArrayList<Bitmap>();

        ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1,artName);
        listView.setAdapter(arrayAdapter);

        try {

            Main2Activity.database = this.openOrCreateDatabase("Arts", MODE_PRIVATE, null);
            Main2Activity.database.execSQL("CREATE TABLE IF NOT EXISTS arts (name VARCHAR, image BLOB)");

            Cursor cursor = Main2Activity.database.rawQuery("SELECT * FROM arts", null);//cursor is for data recieving

            int nameIx = cursor.getColumnIndex("name");
            int imageIx = cursor.getColumnIndex("image");

            cursor.moveToFirst();

            while (cursor != null) {

                artName.add(cursor.getString(nameIx));
                //adding bitmap into artImage
                byte[] byteArray = cursor.getBlob(imageIx);
                //decoding bitmaps
                Bitmap image = BitmapFactory.decodeByteArray(byteArray,0,byteArray.length);
                artImage.add(image);

                cursor.moveToNext();

                arrayAdapter.notifyDataSetChanged();//data degistiyse arrayadapter'a haber veriyor ve guncelleyip kullaniciya gosterir

            }


        } catch (Exception e) {
            e.printStackTrace();
        }

         //selecting saved images
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
                intent.putExtra("info", "old");
                intent.putExtra("name", artName.get(position));
                intent.putExtra("position", position);

                startActivity(intent);

            }
        });

    }
}

ListView from xml

 <ListView
        android:id="@+id/listView"
        android:layout_width="368dp"
        android:layout_height="495dp"
        tools:layout_editor_absoluteX="8dp"
        tools:layout_editor_absoluteY="8dp" />
  • The error message is clear. You are requesting `5397663 bytes` of memory while the available free space allocated for your app is `1143664 bytes`. You may need to scale down your bitmaps first – landrykapela Apr 02 '19 at 11:38
  • how? can you give me sample code? – user10230951 Apr 02 '19 at 11:45
  • check this post https://stackoverflow.com/questions/477572/strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object – landrykapela Apr 02 '19 at 11:50
  • 1
    You need lazy loading for images for cache management. you can use glide or picasso library to load images. Also use RecyclerView which uses view holders and recycle the not visible items in list. – Ahmad Ayyaz Apr 02 '19 at 11:59

1 Answers1

0

A Cursor window has a limitation of 2MB, a row must fit into a Cursor Window, it cannot be split across multiple Cursor Windows and hence your 5Mb image cannot be retrieved via a Cursor (the CursorWindow is effectively a buffer for the Cursor).

The best way of handling such images is to store the image(s) as files and to store the path to the image in the database. This answer shows an example of storing the image path (and also the image when the image size is below a certain size (100k)) and also includes some underlying detail on the subject.

A clumsy way of storing large images, albeit NOT RECOMMENDED, is described at How to use images in Android SQLite that are larger than the limitations of a CursorWindow?

MikeT
  • 51,415
  • 16
  • 49
  • 68