java - SQLite 数据库游标返回错误的资源 ID

标签 java android sqlite resources android-sqlite

我正在尝试使用对 SQLite 数据库中的可绘制资源和字符串资源的引用,以在 fragment 中显示适当的资源。我有一个数据库帮助程序文件来填充数据库,一个数据库实用程序文件来创建游标(或者只是获取数组中的游标数据),以及 fragment 文件。

    DatabaseHelper.java
    DatabaseHelper(Context context) {
            super(context, DB_NAME, null, DB_VERSION);
        }

        private void updateMyDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
            if (oldVersion == 1) {
                db.execSQL("CREATE TABLE FOOD (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                        + "NAME TEXT, "
                        + "IMAGE_RESOURCE_ID INTEGER, "
                        + "QUOTE INTEGER);");

                insertFood(db,"Alcohol", R.drawable.alcohol, R.string.symptom9);
}

private static void insertFood(SQLiteDatabase db, String name, int toxicity, int resourceId, int quote){
        ContentValues foodValues = new ContentValues();
        foodValues.put("NAME", name);
        foodValues.put("TOXICITY", toxicity);
        foodValues.put("IMAGE_RESOURCE_ID", resourceId);
        foodValues.put("QUOTE", quote);
        db.insert("FOOD", null, foodValues);
    }
}

在这里,R.drawable.alcohol = 2131099733

我正在使用 Android Studio,当我将鼠标悬停在要添加到数据库的值上并使用这些值之一显示可绘制对象时,它是正确的可绘制对象,但是当我请求光标(或基于游标),游标包含的值与存储在数据库中的值完全不同,并产生资源未找到错误。

我尝试从辅助方法返回一个数据数组,但这也为可绘制对象和字符串提供了不正确的整数引用,因此,我改为从辅助方法返回光标:

DatabaseUtilities.java
//get all of the database data for a particular food given that food's name
    public static Cursor getFoodById(Context context, long itemId){

        try {
            SQLiteOpenHelper DatabaseHelper = new DatabaseHelper(context);
            SQLiteDatabase db = DatabaseHelper.getReadableDatabase();
            return db.query(DatabaseHelper.FOOD,
                    new String[]{
                            DatabaseHelper.NAME, DatabaseHelper.IMAGE_RESOURCE_ID,
                            DatabaseHelper.QUOTE},
                    "_id = ?", new String[] {Long.toString(itemId)}, null, null, null
            );

        } catch (SQLiteException e) {
            //TODO Add toast - food not available
            return null;
        }
    }

最后,我尝试在此处显示值:

DetailFragment.java
 @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        Cursor items = DatabaseUtilities.getFoodById(getActivity(), itemId);
        if(items.moveToFirst()) {    
            //set appropriate img
            int img = items.getInt(1);
            ImageView photo = (ImageView) view.getRootView().findViewById(R.id.detail_photo);
            photo.setImageResource(img);

            int quote = items.getInt(2);
            TextView desc = (TextView) view.getRootView().findViewById(R.id.detail_text);
            String descText = getString(quote);
            desc.setText(descText);
        }
    }

这是上一个文件中所有游标列的日志输出:

DetailFragment - cursor: Alcohol, 2131165269, 2131558463

Alcohol 后面的值应该是 R.drawable.alcohol, 2131099733,但光标返回的是 2131165269。可绘制对象引用之后的字符串引用也是如此。此外,游标为每个插入的行返回不同的值,它们只是错误的值,我不知道它们来自哪里,或者是否有办法将它们转换为正确的值。

除了数据库没有返回正确的资源引用外,程序中的一切都正常。

最佳答案

不要在表中存储资源的整数 ID。
每次更改资源和重新编译项目时,不能保证它们的值相同。
而是将资源 ID 存储为字符串文字。
因此,将表的定义更改为:

CREATE TABLE FOOD (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                    + "NAME TEXT, "
                    + "IMAGE_RESOURCE_ID TEXT, "
                    + "QUOTE TEXT);

现在将字符串 ID 存储在 IMAGE_RESOURCE_IDQUOTE 列中。
当您使用游标从表中检索这样一个字符串 id 时,您可以通过这种方式获取它的整数 id:

int drawableId = getResources().getIdentifier(drawableString, "drawable", getPackageName());
int stringId = getResources().getIdentifier(stringString, "string", getPackageName()); 

您可能需要向 getResources()getPackageName() 提供有效的 Context,例如:

context.getResources().getIdentifier(drawableString, "drawable", context.getPackageName());

drawableStringstringString 替换为您从表格中检索到的图像和字符串的值。
如果您在表的定义中进行上述建议的更改,则必须从设备/模拟器卸载应用程序并重新运行,以便删除数据库并使用新的表定义重新创建。

关于java - SQLite 数据库游标返回错误的资源 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56134995/

相关文章:

android - 如何在android中实现不自定义的SD卡库?

android - 数组方法返回数组,只有第一个值?

ios - SQLite3 在 iOS 应用程序中生成 no such table 错误

java - System.exit(0) 和 System.exit(-1) 的区别

java - Spring MVC 项目的可选 redis session 存储

Java:如何考虑对马尔可夫链建模?

java - Spring 网络套接字 : message not published

Android 大型关系文本数据的最优存储机制是什么

android - ListView 仅显示 ArrayList(HashMap) 的最后一个元素

django - Django 中 DateTime 字段之间的聚合差异