尝试插入sqlitedatabase时出现多个错误

时间:2019-12-08 17:41:27

标签: java android nullpointerexception

我正在尝试使用sqlitedatabase创建一个应用程序,然后将一些数据(用户提供的姓氏和名字,age,id为自动增量)添加到数据库的字段中,但是出现多个错误,我无法更正它们,尽管我尝试多次更改代码。 这是我的代码: 第一类:FirstActivity

package com.example.dit.hua.ergasia.firstactivity;

import androidx.annotation.RequiresApi;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import static android.content.ContentValues.TAG;

public class FirstActivity extends Activity {
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_activity_main);
Button button1 = findViewById(R.id.Button_1);    //save given data to database when the user clicks the button !
        button1.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onClick(View v) {
                //passing to variables what the user wrote !
                //FIRST NAME
                EditText editTextFirstName = findViewById(R.id.Edit_text_first_name);
                String First_name = editTextFirstName.getText().toString();

                final TextView TextViewFirstName_show_error = (TextView) findViewById(R.id.My_Text_view_first_name);
                if(First_name.isEmpty()) {
//                  Toast.makeText(FirstActivity.this, "First name field is empty!", Toast.LENGTH_SHORT).show();
                    TextViewFirstName_show_error.setText(R.string.Text_view_first_name_error);
                }else {
                    TextViewFirstName_show_error.setText(R.string.show_blank);
                    TextViewFirstName_show_error.setText(First_name);
                }

                //LAST NAME
                EditText editTextLastName = findViewById(R.id.Edit_text_last_name);
                String Last_name  = editTextLastName.getText().toString();

                final TextView TextViewLastName_show_error = (TextView) findViewById(R.id.My_Text_view_last_name);
                if(Last_name.isEmpty()) {
                    TextViewLastName_show_error.setText(R.string.Text_view_last_name_error);
                }else {
                    TextViewLastName_show_error.setText(R.string.show_blank);
                    TextViewLastName_show_error.setText(Last_name);
                }

                //AGE
                EditText editTextAge = findViewById(R.id.Edit_text_age);   // find the EditText, then get its value and put it into variable
                String Age = editTextAge.getText().toString();


                int value=0;
                if (!"".equals(Age)){                                     //  Check if the EditText is empty.  If it is empty, do not try to convert the received value to int. Otherwise, the application will crash.
                    value=Integer.parseInt(Age);                          //parse the value to Integer
                }

                final TextView TextViewAge_show_error = (TextView) findViewById(R.id.My_Text_view_age);
                if(Age.isEmpty()) {        //  Age.length()==0   other way                          //  Check if the EditText is empty.
                    TextViewAge_show_error.setText(R.string.Text_view_age_error);                           //  show error
                }else {
                    TextViewAge_show_error.setText(R.string.show_blank);
                    TextViewAge_show_error.setText(Age);  //h Age krasarei !!!  //ELEGXOS
                }

DataContract datacontractobject = null;
               try {
                    datacontractobject = new DataContract(First_name, Last_name, value);   //cretaing an object every time that the user wants to save data
                }catch(Exception e ){
                    Log.d(TAG, "CREATE OBJECT DATACONTRACTOBJECT ", e);
                    e.getStackTrace();
                    Toast.makeText(FirstActivity.this, "object datacontract not created!", Toast.LENGTH_SHORT).show();
                }finally{
                    Toast.makeText(FirstActivity.this, "object datacontract created!", Toast.LENGTH_SHORT).show();
                }


                //saving to database the data that the user wrote
                boolean didItWork = true;

                DBHelper entry = new DBHelper(FirstActivity.this);
                DBHelper RETURN = null;
                try {
                    RETURN = entry.open(FirstActivity.this);
                }catch(Exception e){
                    Toast.makeText(FirstActivity.this, "open error!", Toast.LENGTH_SHORT).show();
                    Log.d(TAG, "OPEN  ", e);
                    e.getStackTrace();
                }

                try {
 RETURN.createEntry(datacontractobject);    //insert
                    RETURN.close();

                }catch(Exception e) {
                    didItWork = false;
                    Toast.makeText(FirstActivity.this, "Your data were not saved in database!", Toast.LENGTH_SHORT).show();
                    Log.d(TAG, "INSERT ", e);
                    e.getStackTrace();
                }finally
                {
                    if(didItWork) {
                        Toast.makeText(FirstActivity.this, "Your data were saved in database!", Toast.LENGTH_SHORT).show();
                    }
                }

          }
        });

Class:这是一个名为DataContract的合同类

package com.example.dit.hua.ergasia.firstactivity;

public class DataContract {
    //One of the main principles of SQL databases is the schema: a formal declaration of how the database is organized.
    // The schema is reflected in the SQL statements that I use to create my database.
    // This class is a companion class, known as a contract class, which explicitly specifies the layout of my schema in a systematic and self-documenting way.
    int id;
    String lname;
    String fname;
    int age;

    public DataContract(int id, String lname, String fname, int age) {
        this.id = id;
        this.lname = lname;
        this.fname = fname;
        this.age = age;
    }


    public DataContract(String lname, String fname, int age) {
        this.lname = lname;
        this.fname = fname;
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public String getFname() {
        return fname;
    }

    public int getId() {
        return id;
    }

    public String getLname() {
        return lname;
    }
}

第三类:DBHelper,用于与数据库连接并将数据插入到数据库中


package com.example.dit.hua.ergasia.firstactivity;


import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

import static android.content.ContentValues.TAG;

public class DBHelper extends SQLiteOpenHelper implements BaseColumns {


    public static String FIRST_NAME = "_FIRST_NAME";
    public static String LAST_NAME = "_LAST_NAME";
    public static String AGE  ;
    //public static String ID = "0" ;

    public static final String DB_NAME = "MY_DATABASE";
    public static final String DB_TABLE = "MY_DATABASE";         ///"PERSONAL_DATA";
    public static final int DB_VERSION =1;

    public DBHelper ourHelper;
    public final Context ourcontext = null;
    public SQLiteDatabase ourDatabase;


     public DBHelper(@Nullable Context context) {       //pulic constructor: to create a helper object to create, open, and/or manage a database.
        super(context, DB_NAME, null, DB_VERSION);     //Context: to use for locating paths to the the database

    }
    //context        Context: to use for locating paths to the the database This value may be null.
    //name           String: of the database file, or null for an in-memory database This value may be null.
    //factory        SQLiteDatabase.CursorFactory: to use for creating cursor objects, or null for the default This value may be null.
    //version        int: number of the database (starting at 1); if the database is older, onUpgrade(SQLiteDatabase, int, int) will be used to upgrade the database; if the database is newer, onDowngrade(SQLiteDatabase, int, int) will be used to downgrade the database



    // Here are some typical statements that create and delete a table:
    private static final String SQL_CREATE_ENTRIES =
            "CREATE TABLE IF NOT EXISTS " + DB_TABLE + " (" +
                    BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    FIRST_NAME + " TEXT, " +
                    LAST_NAME + " TEXT, "  +
                    AGE + " INTEGER NOT NULL ) ";

    @Override
    public void onCreate(SQLiteDatabase db) {  //create database table

try {
    db.execSQL(SQL_CREATE_ENTRIES);
}catch(Exception e){
    Log.d(TAG, "DB HELPER ONCREATE  ", e);
    e.getStackTrace();
    e.getCause();
    e.getMessage();
    e.getLocalizedMessage();
}
    }
 @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}

 public long createEntry(DataContract contactsContract){     //insert
        ContentValues contentValues = new ContentValues();
        //ID is autoincrement
        try {
            contentValues.put(FIRST_NAME, contactsContract.getFname());
            contentValues.put(LAST_NAME, contactsContract.getLname());
            contentValues.put(AGE, contactsContract.getAge());
        }catch(Exception e ){Log.d(TAG, "DBHELPER CREATE ENTRY  ", e);}
        //in every column i want to add a new row
        //i have created an object type of DataContract, which contains a fname, a lname an an age , so I need getters to "take" fname, lname and age from that object and put them into database each in the column that belongs
        long number = 0;
        try{
             number =ourDatabase.insert(DB_TABLE, null , contentValues);
        }catch (Exception e){
            Log.d(TAG, "DBHELPER INSERT IN CREATE ENTRY ", e);
        }
        return number ;
    }

}

正如我之前所说,在应用程序运行时,logcat中出现多个错误,请插入到databse中! 这些是:

**
E/eglCodecCommon: glUtilsParamSize: unknow param 0x000082da glUtilsParamSize: unknow param 0x000082da
**
** 2019-12-08 19:15:04.944 17665-17665/com.example.dit.hua.ergasia.firstactivity E/SQLiteLog: (1) near "null": syntax error **
** 2019-12-08 19:15:04.948 17665-17665/com.example.dit.hua.ergasia.firstactivity E/SQLiteDatabase: Error inserting null=9 _FIRST_NAME=vhjj _LAST_NAME=vhjvj
    android.database.sqlite.SQLiteException: near "null": syntax error (code 1): , while compiling: INSERT INTO MY_DATABASE(null,_FIRST_NAME,_LAST_NAME) VALUES (?,?,?)  **
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:890)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:501)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
        at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1546)
        at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1417)
        at com.example.dit.hua.ergasia.firstactivity.DBHelper.createEntry(DBHelper.java:129)
        at com.example.dit.hua.ergasia.firstactivity.FirstActivity$4.onClick(FirstActivity.java:165)
        at android.view.View.performClick(View.java:6294)
        at android.view.View$PerformClick.run(View.java:24770)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
2019-12-08 19:15:04.963 17665-17665/com.example.dit.hua.ergasia.firstactivity D/ContentValues: INSERT 
    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.dit.hua.ergasia.firstactivity.DBHelper.close()' on a null object reference
        at com.example.dit.hua.ergasia.firstactivity.DBHelper.close(DBHelper.java:97)
        at com.example.dit.hua.ergasia.firstactivity.DBHelper.close(DBHelper.java:97)
        at com.example.dit.hua.ergasia.firstactivity.FirstActivity$4.onClick(FirstActivity.java:166)
        at android.view.View.performClick(View.java:6294)
        at android.view.View$PerformClick.run(View.java:24770)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)



2019-12-08 19:15:23.914 1621-1643/system_process E/memtrack: Couldn't load memtrack module
2019-12-08 19:15:23.914 1621-1643/system_process W/android.os.Debug: failed to get memory consumption info: -1


2019-12-08 19:19:20.044 1621-1655/system_process E/BatteryExternalStatsWorker: modem info is invalid: ModemActivityInfo{ mTimestamp=0 mSleepTimeMs=0 mIdleTimeMs=0 mTxTimeMs[]=[0, 0, 0, 0, 0] mRxTimeMs=0 mEnergyUsed=0}
2019-12-08 19:19:25.042 1621-1655/system_process I/WifiService: requestActivityInfo uid=1000

我真的是android编程的新手,我很难理解这些错误的含义以及解决方法。如果有人可以帮助我,将不胜感激!

1 个答案:

答案 0 :(得分:2)

只需更新即可使用。您可能正在使用SQLiteDatabase对象,而没有在类级别声明的DBHelper类中初始化。在onCreate中添加一行应该ourDatabase = db;

@Override
public void onCreate(SQLiteDatabase db) {  //create database table

try {
    ourDatabase = db;
    db.execSQL(SQL_CREATE_ENTRIES);
}catch(Exception e){
    Log.d(TAG, "DB HELPER ONCREATE  ", e);
    e.getStackTrace();
    e.getCause();
    e.getMessage();
    e.getLocalizedMessage();
    }
}

以下语句导致空指针异常,因为您正在使用它而未对其进行初始化。

number =ourDatabase.insert(DB_TABLE, null , contentValues);

在下面使用以从您的数据库助手类中获取sqlite db对象,并将其作为参数传递给该函数。或使用此更新类级别变量。

 DBHelper dbHelper = new DBHelper(getContext());

 ourDatabase = dbHelper.getWritableDatabase();

修改: 您在onClick()中有一些sqlite db创建代码,找到它并将其替换为下面的代码。

查找代码:

    //start....
    DBHelper entry = new DBHelper(FirstActivity.this);
                DBHelper RETURN = null;
                try {
                    RETURN = entry.open(FirstActivity.this);
                }catch(Exception e){
                    Toast.makeText(FirstActivity.this, "open error!", Toast.LENGTH_SHORT).show();
                    Log.d(TAG, "OPEN  ", e);
                    e.getStackTrace();
                }

                try {
 RETURN.createEntry(datacontractobject);    //insert
                    RETURN.close();

                }catch(Exception e) {
                    didItWork = false;
                    Toast.makeText(FirstActivity.this, "Your data were not saved in database!", Toast.LENGTH_SHORT).show();
                    Log.d(TAG, "INSERT ", e);
                    e.getStackTrace();
                }
    //end...

要替换的代码:

// start...
DBHelper entry = new DBHelper(FirstActivity.this);
SQLiteDatabase database = entry.getWritableDatabase();             

try {
     entry.createEntry(datacontractobject,database);    //insert
     database.close();
}catch(Exception e) {
     didItWork = false;
     Toast.makeText(FirstActivity.this, "Your data were not saved in database!", Toast.LENGTH_SHORT).show();
     Log.d(TAG, "INSERT ", e);
     e.getStackTrace();
}
//end...
DBHelper类中的

如下更新了所需的函数,因为在调用时我们已经更改了上面的签名,因此我们也在此处进行更改。 现在,您的 createEntry 方法应如下所示。

 public long createEntry(DataContract contactsContract, SQLiteDatabase database ){     //insert
    ContentValues contentValues = new ContentValues();
    //ID is autoincrement
    try {
        contentValues.put(FIRST_NAME, contactsContract.getFname());
        contentValues.put(LAST_NAME, contactsContract.getLname());
        contentValues.put(AGE, contactsContract.getAge());
    }catch(Exception e ){Log.d(TAG, "DBHELPER CREATE ENTRY  ", e);}
    //in every column i want to add a new row
    //i have created an object type of DataContract, which contains a fname, a lname an an age , so I need getters to "take" fname, lname and age from that object and put them into database each in the column that belongs
    long number = 0;
    try{ 
         //changed the db variable now to method parameter instead of class one
         number = database.insert(DB_TABLE, null , contentValues);
    }catch (Exception e){
        Log.d(TAG, "DBHELPER INSERT IN CREATE ENTRY ", e);
    }
    return number ;
}