我正在尝试使用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编程的新手,我很难理解这些错误的含义以及解决方法。如果有人可以帮助我,将不胜感激!
答案 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 ;
}