我正在尝试使用AndroidStudio 3.0.1从SQLite数据库中检索数据,但得到以下异常。我一直在寻找错误,但无法找到一个好的解决方案。这是我的代码。
将数据插入数据库
public boolean insertCoins(int coins){
SQLiteDatabase db=this.getReadableDatabase ();
ContentValues values=new ContentValues ();
values.put(Col1,coins);
long result=db.insert(Table_Name,null,values);
if (result != -1) {
return true;
} else {
return false;
}
}
代码在这里给出错误
public Cursor getData(){
Cursor res = this.getReadableDatabase ().rawQuery("select sum("+Col1+") from "+Table_Name+"",null);
return res;
}
这是方法id Plying_Window Class ,它正在调用 Database_Helper 的 insertCoins 方法
public void insertCoins( ){
Database_Helper db=new Database_Helper ( this );
boolean isInserted=db.insertCoins( 5 );
if(isInserted){
Toast.makeText ( Playing_Window.this, getString( R.string.c_add),Toast.LENGTH_LONG ).show ();}
}
这是级别,它正在调用 Database_Helper 的 getData 方法。
public class Levels extends AppCompatActivity {
static int Easy_lvl_counter=0,Medium_lvl_counter=0,Hard_lvl_counter=0;
public TextView display_coins;
int tot_coins =coin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_levels );
Actions ();get ();
set ();
}
void set(){
int c=get();
tot_coins=c;
display_coins.setText ( String.valueOf ( c ) );
}
Button btn_level1,btn_level2,btn_level3,btn_level4,btn_level5,btn_level6,btn_level7,btn_level8,btn_level9,btn_level10,btn_mainMenu;
public void Actions(){
display_coins=findViewById ( R.id.coins );
btn_level1= findViewById ( R.id.btn_level1 );
btn_level2=findViewById ( R.id.btn_level2 );
btn_level3=findViewById ( R.id.btn_level3 );
btn_level4=findViewById ( R.id.btn_level4 );
btn_level5=findViewById ( R.id.btn_level5 );
btn_level6=findViewById ( R.id.btn_level6 );
btn_level7=findViewById ( R.id.btn_level7 );
btn_level8=findViewById ( R.id.btn_level8 );
btn_level9=findViewById ( R.id.btn_level9 );
btn_level10=findViewById ( R.id.btn_level10 );
btn_mainMenu=findViewById ( R.id.btn_mainMenu );
btn_mainMenu.setOnClickListener ( new View.OnClickListener () {
@Override
public void onClick(View v) {
finish ();
Medium_lvl_counter=0;Easy_lvl_counter=0;Hard_lvl_counter=0;
}
} );
btn_level1.setOnClickListener ( new View.OnClickListener () {
@Override
public void onClick(View v) {
switch (Choice){
case 1:{Easy_lvl_counter = 1; Medium_lvl_counter=0;Hard_lvl_counter=0;
if(tot_coins>=0)startActivity ( new Intent ( getApplicationContext (),Playing_Window.class ) );break;}
case 2:{Medium_lvl_counter=1;Hard_lvl_counter=0;Easy_lvl_counter=0;
if(tot_coins>=50){startActivity ( new Intent ( getApplicationContext (),Playing_Window.class ) );}
else{Toast .makeText( Levels.this, R.string.txt_coins_short, Toast.LENGTH_SHORT).show();}break; }
case 3:{Hard_lvl_counter=1;Easy_lvl_counter = 0; Medium_lvl_counter=0;
if(tot_coins>=100)startActivity ( new Intent ( getApplicationContext (),Playing_Window.class ) );
else{Toast .makeText( Levels.this,R.string.txt_coins_short, Toast.LENGTH_SHORT).show();}break; }
}
}
} );............}
public int get(){
Database_Helper dbHelper=new Database_Helper (Levels.this);
Cursor cursor=dbHelper.getData ();
if(cursor.getCount ()==0){return 0;}
else{
while(cursor.moveToNext ()){
String db_coins=cursor.getString ( 0);
if(coin ==-1)coin=0;
else coin=Integer.valueOf ( db_coins );
}
}
return coin;
}
static int coin=0;
}
这是 playingWindow类
public class Playing_Window extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
setContentView ( R.layout.activity_playing__window );
Actions ();
}
Levels obj_lev;
boolean timer_Count=false;
private EditText box1, box2 , box3, box4, box5, box6, box7, box8, box9, box10, box11, box12, box13, box14, box15, box16, box17, box18, box19 , box20, box21, box22, box23, box24, box25;
private AlertDialog.Builder builder;AlertDialog alertdialog;
private CountDownTimer timer;
void Actions() {
obj_lev=new Levels ();
builder = new AlertDialog.Builder(Playing_Window.this);
.
.
.
.
void dialogShow(){
builder.setMessage ( getString( R.string.con_Text) );
builder.setPositiveButton( R.string.txt_ok, new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
Levels obj=new Levels ();obj.get ();
finish ();
}
});
alertdialog=builder.create();
alertdialog.show();
}
void dialogShowIncomplete(){
builder.setMessage ( "Fill all the Boxes Correctly ! " );
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
alertdialog=builder.create();
alertdialog.show();
}
.
.
.
public void insertCoins( ){
Database_Helper db=new Database_Helper ( this );
boolean isInserted=db.insertCoins( 5 );
if(isInserted){
Toast.makeText ( Playing_Window.this, getString(
R.string.c_add),Toast.LENGTH_LONG ).show ();}
}
}
这是我的例外的堆栈跟踪。谢谢你的时间
Process: com.sudoku.jamshaid.sudoku, PID: 23032
java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:267)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
at com.sudoku.jamshaid.sudoku.Database_Helper.getData(Database_Helper.java:45)
at com.sudoku.jamshaid.sudoku.Levels.get(Levels.java:241)
at com.sudoku.jamshaid.sudoku.Playing_Window$3.onClick(Playing_Window.java:2555)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
答案 0 :(得分:0)
以下是您的代码,每个使用db i,e SQLiteDatabase的地方。
再次使用insertCoins时,您将创建SQliteDatabase引用。
public boolean insertCoins(int coins){
SQLiteDatabase db=this.getReadableDatabase ();
全球使用一个SQLiteDatabase db;
试试这个:
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL ( "create table " + Table_Name + " (ID integer PRIMARY KEY AUTOINCREMENT," + Col1 + " INTEGER not null " + ")" );
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL ( "Drop table if exists "+Table_Name );
onCreate ( db );
}
public boolean insertCoins(int coins){
db=this.getReadableDatabase ();
ContentValues values=new ContentValues ();
values.put(Col1,coins);
long result=db.insert(Table_Name,null,values);
if (result != -1) {
return true;
} else {
return false;
}
}
从Sqlite获取数据的代码:
private void setData() {
Constants.cList = new ArrayList<LoadDataResult>();
// Select All Query
String selectQuery = "SELECT * FROM " + Constants.TABLE_NAME;
db = databaseHelper.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
LoadDataResult product = new LoadDataResult();
product.setName(cursor.getString(1));
product.setSku(cursor.getString(2));
product.setUpc(cursor.getString(3));
product.setAssoc_upc(cursor.getString(4));
product.setPrice(cursor.getString(5));
product.setDisplaySize(cursor.getString(6));
product.setDisplaySizeYes(Integer.parseInt(String.valueOf(cursor.getInt(7))));
product.setStatus(cursor.getString(8));
Log.e("DATASQL",""+cursor.getString(3));
// Adding contact to list
Constants.cList.add(product);
} while (cursor.moveToNext());
// utils.hideDialog();
}
}
尝试使用它,更改你的getData()并尝试
public Cursor getData(){
String selectQuery = "SELECT * FROM " + Table_Name;
Cursor res = this.getReadableDatabase().rawQuery(selectQuery,null);
return res;
}
答案 1 :(得分:0)
obj_lev=new Levels ();
...
Levels obj=new Levels ();obj.get ();
从不如何在Android中启动活动。您的错误是因为Activity是Context对象,而您的数据库需要Context。当您在Activity上调用new
时,没有启动任何Activity生命周期(例如onCreate,永远不会执行),并且它的Context永远不会被设置,因此它为null,并传递给数据库处理程序,这是你在尝试使用它时遇到问题的地方。
即使查看其余的代码,我也不确定您希望Level类中的按钮如何工作,或者在调用onCreate中的任何方法时都要设置文本视图。
你需要实际start it。
总的来说,您的get()
方法无法在&#34;播放窗口中播放&#34;因为在Android开发中保留一个Activity的实例只是一个错误的模式。
您需要的是包含数据库的Context的包装器
public class LevelDB { // this is not an Activity
private Context mContext;
private Database_Helper mDb;
public LevelDB(Context c) {
mContext = c;
mDb = new Database_Helper(c);
}
public int get() {
SQLiteDatabase db = mDb.getReadableDatabase();
return -1; // TODO: query the database
}
}
现在你会做
LevelDB obj=new LevelDB (Playing_Window.this);
int value = obj.get ();
通过传递正确的Context,您可以在其他活动中执行完全相同的操作。
例如
public TextView display_coins;
LevelDB mDb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_levels );
display_coins = findViewById(...);
mDb = new LevelDB (Levels.this);
int value = mDb.get ();
display_coins.setText(""+value);
}
另一种方法是使用您当前的代码,但使用静态方法而不是使用Context
public static int get(Context c){
Database_Helper dbHelper=new Database_Helper (c);
Cursor cursor=dbHelper.getData ();
除此之外,我在评论中指出了房间图书馆。使用它 - 它可以帮助您更好地管理数据库(但它不会解决您错误地使用活动的错误)
答案 2 :(得分:-2)
我认为这是因为你使用的是getReadableDatabase,你应该使用getWritableDatabase。如果不是这样,那么Col1可能不存在/没有任何内容,或者您的数据库可能尚未创建。它是一个空指针,不应该太难以弄清楚