【关于Android 中SQLite的insert与query方法报错insert】
我觉得应该是SQLite相关操作的问题,但是找了很久找不到哪里报错。
代码是跟着网上一个项目的源码写的。这个项目没报错并且能正常运行,我一insert就报:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference
找了78个小时都没找到
下面是logcat的报错信息
04-28 06:40:53.227 1344-1654/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 14441882 , only wrote 14304701
04-28 06:40:56.113 1950-3104/com.android.inputmethod.latin D/EGL_emulation: eglMakeCurrent: 0xae4549c0: ver 3 1 (tinfo 0xae4524e0)
04-28 06:40:56.114 1950-3104/com.android.inputmethod.latin E/Surface: getSlotFromBufferLocked: unknown buffer: 0xa20fa0e0
04-28 06:40:57.874 9152-9152/com.example.nero.thecashregistersystem D/MyDBOpenHelper: query sql: select rowid,name,goods_number,in_price,out_price,'update_time 'from goods where name='123';
04-28 06:40:57.874 9152-9152/com.example.nero.thecashregistersystem D/AndroidRuntime: Shutting down VM
--------- beginning of crash
04-28 06:40:57.874 9152-9152/com.example.nero.thecashregistersystem E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.nero.thecashregistersystem, PID: 9152
java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference
at com.example.nero.thecashregistersystem.db.MyDBOpenHelper.query(MyDBOpenHelper.java:212)
at com.example.nero.thecashregistersystem.db.MyDBOpenHelper.insert(MyDBOpenHelper.java:140)
at com.example.nero.thecashregistersystem.db.MyDBOpenHelper.insert(MyDBOpenHelper.java:128)
at com.example.nero.thecashregistersystem.add_goodsActivity.onClick(add_goodsActivity.java:108)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
上代码:
MyDBOpenHelper.java
package com.example.nero.thecashregistersystem.db;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.example.nero.thecashregistersystem.bean.goodsInfo;
import com.example.nero.thecashregistersystem.bean.goodsInfo;
import java.util.ArrayList;
public class MyDBOpenHelper extends SQLiteOpenHelper {
//from storage(这里是跟着项目源码敲的)
private static final String TAG = "MyDBOpenHelper";
private static final String DB_NAME = "my.db";
private static MyDBOpenHelper mHelper = null;
private SQLiteDatabase mDB = null;
private static final String TABLE_NAME = "goods";
private static final int DB_VERSION = 1;
private MyDBOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
private MyDBOpenHelper(Context context,int version) {
super(context, DB_NAME, null, version);
}
@Override
//数据库第一次创建时被调用
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE goods(good_ID INTEGER PRIMARY KEY AUTOINCREMENT," +
"name VARCHAR(20) NOT NULL," +
"goods_number INTEGER NOT NULL," +
"in_price REAL(8) NOT NULL," +
"out_price REAL(8) NOT NULL," +
"update_time VARCHAR NOT NULL)");
db.execSQL("CREATE TABLE bill(bill_ID INTEGER PRIMARY KEY AUTOINCREMENT," +
"name VARCHAR(20)," +
"quantily INTEGER," +
"goods_number INTEGER NOT NULL," +
"in_price REAL(8) NOT NULL," +
"out_price REAL(8) NOT NULL ," +
"sum_price REAL(8)," +
"FOREIGN KEY(name) REFERENCES goods(name)," +
"FOREIGN KEY(in_price) REFERENCES goods(in_price)," +
"FOREIGN KEY(out_price) REFERENCES goods(out_price))");
db.execSQL("CREATE TABLE orders(bill_ID INTEGER ,name VARCHAR(20)," +
"quantily INTEGER ," +
"goods_number INTEGER," +
"out_price REAL(8)," +
"sum_price REAL(8)," +
"FOREIGN KEY(bill_ID) REFERENCES bill(bill_ID)," +
"FOREIGN KEY(name) REFERENCES goods(name)," +
"FOREIGN KEY(out_price) REFERENCES goods(out_price)," +
"FOREIGN KEY(sum_price) REFERENCES bill(sum_price))");
}
//软件版本号发生改变时调用
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL");
}
public static MyDBOpenHelper getInstance(Context context, int version) {
if (version > 0 && mHelper == null) {
mHelper = new MyDBOpenHelper(context, version);
} else if (mHelper == null) {
mHelper = new MyDBOpenHelper(context);
}
return mHelper;
}
public SQLiteDatabase openReadLink() {
if (mDB == null || mDB.isOpen() != true) {
mDB = mHelper.getReadableDatabase();
}
return mDB;
}
public SQLiteDatabase openWriteLink() {
if (mDB == null || mDB.isOpen() != true) {
mDB = mHelper.getWritableDatabase();
}
return mDB;
}
public void closeLink() {
if (mDB != null && mDB.isOpen() == true) {
mDB.close();
mDB = null;
}
}
public String getDBName() {
if (mHelper != null) {
return mHelper.getDatabaseName();
} else {
return DB_NAME;
}
}
public int delete(String condition) {
int count = mDB.delete(TABLE_NAME, condition, null);
return count;
}
public int deleteAll() {
int count = mDB.delete(TABLE_NAME, "1=1", null);
return count;
}
public long insert(goodsInfo info) {
ArrayList<goodsInfo> infoArray = new ArrayList<goodsInfo>();
infoArray.add(info);
//这里的insert中的infoArray不为null,已经验证过了
// if(infoArray == null){
//
// Log.d("infoArray 为null","infoArray 为null");
// }else {
// Log.d("不为null","不为null");
// }
return insert(infoArray);//logcat报错中有提示到这行
}
public long insert(ArrayList<goodsInfo> infoArray) {
long result = -1;
for (int i = 0; i < infoArray.size(); i++) {
goodsInfo info = infoArray.get(i);
ArrayList<goodsInfo> tempArray = new ArrayList<goodsInfo>();
// 如果存在同名记录,则更新记录
// 注意条件语句的等号后面要用单引号括起来
if (info.name != null && info.name.length() > 0) {
String condition = String.format("name='%s'", info.name);
tempArray = query(condition);
if (tempArray.size() > 0) {
update(info, condition);
result = tempArray.get(0).rowid;
continue;
}
}
// 如果存在同样的goods_number,则更新记录
if (info.goods_number != null && info.goods_number.length() > 0) {
String condition = String.format("goods_number='%s'", info.goods_number);
tempArray = query(condition);//logcat报错中有提示到这行
if (tempArray.size() > 0) {
update(info, condition);
result = tempArray.get(0).rowid;
continue;
}
}
// 不存在唯一性重复的记录,则插入新记录
ContentValues cv = new ContentValues();
cv.put("name", info.name);
cv.put("in_price", info.in_price);
cv.put("out_price", info.out_price);
cv.put("quantily", info.quantily);
cv.put("update_time", info.update_time);
result = mDB.insert(TABLE_NAME, "", cv);//logcat报错中有提示到这行
// Log.d("这里result:"+result,"这里result:"+result);
//这里是Log.d没有打印
// 添加成功后返回行号,失败后返回-1
if (result == -1) {
return result;
}
}
return result;
}
public int update(goodsInfo info, String condition) {
ContentValues cv = new ContentValues();
cv.put("name", info.name);
cv.put("in_price", info.in_price);
cv.put("out_price", info.out_price);
cv.put("quantily", info.quantily);
cv.put("quantily", info.quantily);
int count = mDB.update(TABLE_NAME, cv, condition, null);
return count;
}
public int update(goodsInfo info) {
return update(info, "rowid=" + info.rowid);
}
public ArrayList<goodsInfo> query(String condition) {
String sql = String.format("select rowid,name,goods_number,in_price,out_price," +
// "quantily,sum_price," +
"'"+"update_time "+"'"+"from %s where %s;", TABLE_NAME, condition);
Log.d(TAG, "query sql: " + sql);
ArrayList<goodsInfo> infoArray = new ArrayList<goodsInfo>();
Cursor cursor = mDB.rawQuery(sql, null);//logcat报错中有提示到这行
if (cursor.moveToFirst()) {
for (; ; cursor.moveToNext()) {
goodsInfo info = new goodsInfo();
info.rowid = cursor.getLong(0);
info.goods_number = cursor.getString(0);
info.in_price = cursor.getDouble(0);
info.out_price = cursor.getDouble(0);
info.quantily = cursor.getInt(0);
info.sum_price = cursor.getDouble(0);
if (cursor.isLast() == true) {
break;
}
}
}
cursor.close();
return infoArray;
}
// }
}
在activity里的insert代码:
@Override
protected void onStart() {
super.onStart();
mHelper = MyDBOpenHelper.getInstance(this, 2);
mHelper.openWriteLink();
}
@Override
protected void onStop() {
super.onStop();
mHelper.closeLink();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.button_addgoods) {
String name = et_name.getText().toString();
String goods_number = et_good_number.getText().toString();
String in_price = et_in_price.getText().toString();
String out_price = et_out_price.getText().toString();
if (name==null || name.length()<=0) {
showToast("请先填写商品名称");
return;
}
if (goods_number==null || goods_number.length()<=0) {
showToast("请先填写商品编码");
return;
}
if (in_price==null || in_price.length()<=0) {
showToast("请先填写进货价");
return;
}
if (out_price==null || out_price.length()<=0) {
showToast("请先填写出售价");
return;
}
goodsInfo info = new goodsInfo();
info.name = name;
info.goods_number = goods_number;
info.in_price = Long.parseLong(in_price);
info.out_price = Float.parseFloat(out_price);
info.update_time = DateUtil.getNowDateTime("yyyy-MM-dd HH:mm:ss");
mHelper.insert(info);//logcat中提示到这行
showToast("数据已写入SQLite数据库");
}
}
希望各位哥哥姐姐能告诉我哪里出错了。
(ps:如果有人愿意指导我这个project就更好了,这个project快弄完了,弄完数据库就弄个类似购物车 加减计算就ok了)