android - 如何修复我的 Android SQLite 数据库?

标签 android database sqlite android-sqlite android-database

我是一名开发 Android 应用程序的初级程序员,所以我真的需要你的帮助。 我知道我的问题很长,但如果你们能回答我的问题,我将不胜感激

我正在制作一个从表格中的多个单词中随机选择一个单词的应用。

因此,我用 SQLite 创建了我的数据库。我试过这些东西。

  1. 我制作了 WordDBHelper 以使用 SQLiteOpenHelper
  2. 我制作了 WordDBRecord 以将记录放入表中
  3. 我制作了 WordActivty 以打开数据库并查看通过 TextView.setText() 从表格中选择的单词。

这些是我的代码

  1. 文字 Activity
public class WordActivity extends AppCompatActivity {

    private WordDBRecord wordDBRecord;
    String category = wordDBRecord.category;
    String word = wordDBRecord.word;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_word);
        TextView t1 = (TextView) findViewById(R.id.textViewCategory);
        TextView t2 = (TextView) findViewById(R.id.textViewWord);

        wordDBRecord = new WordDBRecord(this);
        wordDBRecord.open();
        wordDBRecord.DBSearch("KeyWordDB");
        t1.setText(category);
        t2.setText(word);
        wordDBRecord.close();
        }
    }
  1. WordDBHelper(使用 SQLite Open Helper)
    import static android.content.ContentValues.TAG;

    public class WordDBHelper extends SQLiteOpenHelper {
         static final String TABLE_NAME = "KeyWordDB";

    public WordDBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        Log.d(TAG, "DataBaseHelper");
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        Log.d(TAG, "Table Create");

        String createQuery = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME +
                "( ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
                "CATEGORY TEXT NOT NULL, " +
                "WORD TEXT NOT NULL);";
        sqLiteDatabase.execSQL(createQuery);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        Log.d(TAG, "Table onUpgrade");
        String createQuery = "DROP TABLE IF EXISTS " + TABLE_NAME + ";";
        sqLiteDatabase.execSQL(createQuery);
        }
    }

3.WordDBRecord(放记录类)

    import static android.content.ContentValues.TAG;

    public class WordDBRecord {
    public String id;
    public String category;
    public String word;
    private Context context;
    private WordDBHelper dbHelper;
    private SQLiteDatabase database;

    public WordDBRecord(Context c) {
        context = c;
    }

    public WordDBRecord open() throws SQLException {
        dbHelper = new WordDBHelper(context, "DB", null, 1);
        database = dbHelper.getWritableDatabase();

          dbInsert("KeyWordDB", "Movie", "Harry Potter");

        return this;
    }

    public void DBSearch(String tableName) {
        Cursor cursor = null;
        try {
            cursor = database.query(tableName, null, null, null, null, null, null);
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    id = cursor.getString(cursor.getColumnIndex("ID"));
                    category = cursor.getString(cursor.getColumnIndex("CATEGORY"));
                    word = cursor.getString(cursor.getColumnIndex("WORD"));
                }
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    public void close() {
        database.close();
        dbHelper.close();
    }

    public void dbInsert(String tableName, String category, String word) {
        Log.d(TAG, "Insert Data ");

        ContentValues contentValues = new ContentValues();

        contentValues.put("CATEGORY", category);
        contentValues.put("WORD", word);

        long id = database.insert(tableName, null, contentValues);
        Log.d(TAG, "id: " + id);
    }

    }

所以我运行了我的应用程序,但未能打开应用程序。单击我的应用程序时,我的应用程序停止了。 我收到了那些 Logcats

    2019-12-15 11:37:59.005 22791-22791/org.techtown.worddbpractice E/AndroidRuntime: FATAL EXCEPTION: main
    Process: org.techtown.worddbpractice, PID: 22791
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{org.techtown.worddbpractice/org.techtown.worddbpractice.WordActivity}: java.lang.NullPointerException: Attempt to read from field 'java.lang.String org.techtown.worddbpractice.WordDBRecord.category' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2849)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045)
        at android.app.ActivityThread.-wrap14(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6776)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
     Caused by: java.lang.NullPointerException: Attempt to read from field 'java.lang.String org.techtown.worddbpractice.WordDBRecord.category' on a null object reference
        at org.techtown.worddbpractice.WordActivity.<init>(WordActivity.java:17)
        at java.lang.Class.newInstance(Native Method)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1086)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2839)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045) 
        at android.app.ActivityThread.-wrap14(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6776) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386) 

我真的很想解决这些问题,但我不知道如何... 如果有人回答我的超长问题,我将非常感激。 谢谢

最佳答案

说明

您面临的问题是,当您使用 private WordDBRecord wordDBRecord; 这会将变量 wordDBRecord 声明为 WordDBRecord 类型,这不是 primative键入一个 Object

声明一个不是原始类型的变量会导致该变量为null(即不存在对象的实例(尚未创建对象))。

  • 在上面标题为 默认值 部分的链接中,它包括:- enter image description here

因此,当遇到下一行 String category = wordDBRecord.category; 时,no object wordDBRecord 而不是 pointer to该对象设置为 null 以表明这一点。因此,当尝试从对象中获取类别时,您会得到空指针异常(您无法从无到有)。

如果遇到下一行 String word = wordDBRecord.word;,将导致相同的问题。

如何修复(空指针异常)

修复很简单,在实例化 wordDBRecord 之前,不要尝试使用 wordDBRecord 来设置类别和词的值。实例化由行 wordDBRecord = new WordDBRecord(this); 完成。

因此,您只想声明 categoryword 变量。例如

public class WordActivity extends AppCompatActivity {

    private WordDBRecord wordDBRecord; //<<<<< only declares wordDBrecord so it is null
    String category; //<<<<< CHANGED TO ONLY DECLARE category
    String word; //<<<<< CHANGED TO ONLY DECALRE word

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView t1 = (TextView) findViewById(R.id.textViewCategory);
        TextView t2 = (TextView) findViewById(R.id.textViewWord);

        wordDBRecord = new WordDBRecord(this); //<<<<< instantiates wordDBRecord so it is now not null
        wordDBRecord.open();
        wordDBRecord.DBSearch("KeyWordDB");
        t1.setText(category);
        t2.setText(word);
        wordDBRecord.close();
    }
}

但是 - 完成修复

应用修复后,您将不会在 TextView 中看到电影和哈利波特。

这是因为当上面的代码运行时,它声明了类别和单词,但它们从未被设置(它们是空的,但 setText 方法会对此进行检查并绕过空指针异常)。您需要设置值,例如在 wordDBRecord.DBSearch("KeyWordDB"); 行之后使用:-

        category = wordRecordDB.category;
        word = wordRecordDB.word;
        t1.setText(category);
        t2.setText(word);

因为您可以直接从 wordDBRecord 对象中获取值。甚至不需要具有可变类别和单词。因此,您可以使用更紧凑的:-

public class WordActivity extends AppCompatActivity {

    private WordDBRecord wordDBRecord; //<<<<< only declares wordDBrecord so it is null

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView t1 = (TextView) findViewById(R.id.textViewCategory);
        TextView t2 = (TextView) findViewById(R.id.textViewWord);

        wordDBRecord = new WordDBRecord(this); //<<<<< instantiates wordDBRecord so it is now not null
        wordDBRecord.open();
        wordDBRecord.DBSearch("KeyWordDB");
        t1.setText(wordDBRecord.category);
        t2.setText(wordDBRecord.word);
        wordDBRecord.close();
    }
}

使用上面的结果:-

enter image description here

日志包含:-

2019-12-16 10:14:37.773 D/Constraints: DataBaseHelper
2019-12-16 10:14:37.789 D/Constraints: Table Create
2019-12-16 10:14:37.794 D/Constraints: Insert Data 
2019-12-16 10:14:37.798 D/Constraints: id: 1

附加

在类似的主题上,SQliteDatabase 查询方法永远不会返回空的 Cursor。不需要在检索它之前将 Cursor 设置为 null 并在检索它之后检查它是否为 null。

因此,您的 DBSearch 方法可能是:-

public void DBSearch(String tableName) {
    Cursor cursor = database.query(tableName,null,null,null,null,null,null);
    while (cursor.moveToNext()) {
        id = cursor.getString(cursor.getColumnIndex("ID"));
        category = cursor.getString(cursor.getColumnIndex("CATEGORY"));
        word = cursor.getString(cursor.getColumnIndex("WORD"));
    }
    cursor.close();
}

关于android - 如何修复我的 Android SQLite 数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59340848/

相关文章:

android - 如何修复android中的 ‘ChipGroup IllegalStateException’错误

java - 如何在 Base 适配器中停止文本到语音

sql - 选择 NOT IN 多列

android - 拦截来自安卓应用的流量

Android Studio 1.0 在 dexDebug 或 dexRelease 构建失败

c# - 获取数据行到 C# 对象

Java 和数据库查询?

android - SQLite 数据库不插入值

java - 将 SQLite 数据库转换为 Java Arraylist

java - 从小部件类连接到数据库