我的列表视图无法显示数据库中的所有元素

Posted

技术标签:

【中文标题】我的列表视图无法显示数据库中的所有元素【英文标题】:my listview can't show all elements in database 【发布时间】:2019-08-23 17:19:22 【问题描述】:

我有一个将名称和图像存储在数据库中的应用程序。然后我在 listview 上打印图像的名称。但我只能从数据库中看到前三个元素。它显示窗口已满错误。数据库没有问题,我通过sqlitebrowser检查了数据库,所有元素都存在。可能我的arrayadapter有问题。有什么问题?图像也很小30kb。 当我尝试查看 ListView 上的所有图像时出错

错误

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 方法

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

            
        );

    

来自 xml 的列表视图

 <ListView
        android:id="@+id/listView"
        android:layout_
        android:layout_
        tools:layout_editor_absoluteX="8dp"
        tools:layout_editor_absoluteY="8dp" />

【问题讨论】:

错误信息很清楚。您正在请求5397663 bytes 的内存,而为您的应用分配的可用空间为1143664 bytes。您可能需要先缩小位图 怎么样?你能给我示例代码吗? 查看此帖***.com/questions/477572/… 您需要延迟加载图像以进行缓存管理。您可以使用 glide 或 picasso 库来加载图像。还可以使用 RecyclerView,它使用视图持有者并回收列表中不可见的项目。 【参考方案1】:

光标窗口有 2MB 的限制,一行必须适合光标窗口,不能跨多个光标窗口拆分,因此无法通过光标检索 5Mb 图像(光标窗口实际上是光标的缓冲区)。

处理此类图像的最佳方法是将图像存储为文件,并将图像的路径存储在数据库中。 This answer 显示了存储图像路径的示例(以及图像大小低于特定大小 (100k) 时的图像),还包括有关主题的一些基本细节。

在How to use images in Android SQLite that are larger than the limitations of a CursorWindow?

中描述了一种存储大图像的笨拙方式,尽管不推荐

【讨论】:

以上是关于我的列表视图无法显示数据库中的所有元素的主要内容,如果未能解决你的问题,请参考以下文章

无法在我的颤振演示应用程序中的列表视图中显示网格视图

SwiftUI 中的列表视图在列表上方显示我无法摆脱的灰色区域

jquery mobile外部面板中的可折叠列表视图无法正确显示

无法从SqFLite显示ListView

无法在本机反应中显示平面列表中的所有数据

无法在 Laravel 中的模型视图中显示数据