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

问题描述 投票:0回答:2

我是制作Android应用程序的初学者,所以我真的需要您的帮助。我知道我的问题太长了,但是如果你们回答我的任务,我将不胜感激

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

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

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

这些是我的代码

  1. 文字活动
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) 

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

android database sqlite android-sqlite android-database
2个回答
0
投票

请在DBSearch()方法中尝试此查询。

public void DBSearch(String tableName) {
    Cursor cursor = null;
    try {
Cursor cursor = db.rawQuery("SELECT name FROM "+tablename, 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();
        }
    }
}

0
投票

说明

您面临的问题是,当您使用private WordDBRecord wordDBRecord;时,它声明变量wordDBRecord的类型为WordDBRecord,它不是primative类型,而是Object] >

Declaring

不是原始类型的变量导致该变量为null(即,不存在该对象的实例(尚未创建该对象))。
  • 在标题为[[默认值部分的上面的链接中,它包括:-enter image description here
  • 因此,当遇到下一行

    String category = wordDBRecord.category;

时,会出现no object wordDBRecord,而不是指向对象的指针设置为null进行指示。因此,当尝试从对象中获取类别时,您将获得null指针异常(无法一无所获)。

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

如何解决(空指针异常)

修复很简单,

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

这样,您只想声明

category

word变量。例如
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(); } }
但是-完整修复

应用此修复程序后,您将

not在TextViews中看到电影和哈利·波特。

这是因为当上面的代码运行时,它声明了类别和单词,但是它们从未设置(

它们为空,但是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查询方法将永远不会返回null的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(); }
© www.soinside.com 2019 - 2024. All rights reserved.