我是StackOverFlow和Android开发中的新手。实际上,这是我开发Android应用程序的第一个真正的项目。
从MySQLiteDefinitionHelper调用名为deleteDictionary()的函数或方法时遇到问题。我通过使用onItemLongCLick触发它来调用我的DefinitionHomeActivity中的方法,然后弹出一个对话框菜单,选择添加,查看和删除的选项。一旦用户单击删除选项,该方法将被真正触发。
一开始,我想使用该方法删除数据库中的表。但是,发生错误并导致应用程序在触发事件时停止。
我认为它可能与数据库错误有关。然后我更改函数以执行一些Log.d()并注释所有具有数据库操作的代码,但仍然会出现相同的错误。
我从互联网上引用了很多资源并改变了我的一些编码,但仍然没有改变任何东西。我希望有人可以帮助我并解释实际发生的事情。谢谢。
这是我的Bean Java文件,名为DefinitionObject.java
package com.example.myidictionary;
public class DefinitionObject {
private int id;
private String word;
private String definition;
private String example;
private String sentence;
public DefinitionObject()
{
}
public DefinitionObject(int id, String word, String definition,
String example, String sentence) {
super();
this.id = id;
this.word = word;
this.definition = definition;
this.example = example;
this.sentence = sentence;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public String getDefinition() {
return definition;
}
public void setDefinition(String definition) {
this.definition = definition;
}
public String getExample() {
return example;
}
public void setExample(String example) {
this.example = example;
}
public String getSentence() {
return sentence;
}
public void setSentence(String sentence) {
this.sentence = sentence;
}
@Override
public String toString() {
/*return "getId= " + getId() + ",\n getWord= "
+ getWord() + ",\n getDefinition= " + getDefinition()
+ ",\n getExample= " + getExample() + ",\n getSentence="
+ getSentence() +"\n\n";*/
return word;
}
}
这是我的MySQLiteDefinitionHelper.java
package com.example.myidictionary;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
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 android.widget.Toast;
import com.example.myidictionary.TableName;
public class MySQLiteDefinitionHelper extends SQLiteOpenHelper {
//db version
private static final int DATABASE_VERSION = 1;
// db name
private static final String DATABASE_NAME = "DefinitionDB";
// Table Columns names
private static final String KEY_ID = "d_id";
private static final String KEY_WORD = "d_word";
private static final String KEY_DEFINITION = "d_definition";
private static final String KEY_EXAMPLE = "d_example";
private static final String KEY_SENTENCE = "d_sentence";
private static final String[] COLUMNS = {KEY_ID,KEY_WORD,KEY_DEFINITION,KEY_EXAMPLE,KEY_SENTENCE};
public MySQLiteDefinitionHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
//SQL statement to create ? table
db.execSQL("CREATE TABLE DefinitionTable (" +
KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_WORD + " TEXT NOT NULL, " +
KEY_DEFINITION + " TEXT NOT NULL, " +
KEY_EXAMPLE + " TEXT, " +
KEY_SENTENCE + " TEXT)");
//db.rawQuery("CREATE TABLE books (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, author TEXT )", null);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//drop table if exists
db.execSQL("DROP TABLE IF EXISTS " + TableName.getTblName());
//create fresh definition table
this.onCreate(db);
}
public void createDefinitionTable(SQLiteDatabase db)
{
//SQL statement to create ? table
db.execSQL("CREATE TABLE "+ TableName.getTblName()+" (" +
KEY_ID+ " INTEGER PRIMARY KEY, " +
KEY_WORD+ " TEXT NOT NULL, " +
KEY_DEFINITION+ " TEXT NOT NULL, " +
KEY_EXAMPLE+ " TEXT, " +
KEY_SENTENCE+ " TEXT");
}
//----------------------------------------------- CRUD operations
public void addDefinition(DefinitionObject defObj)
{
Log.d("addDefinition", defObj.toString());
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(KEY_ID, defObj.getId());
values.put(KEY_WORD, defObj.getWord()); // get title
values.put(KEY_DEFINITION, defObj.getDefinition());
values.put(KEY_EXAMPLE, defObj.getExample());
values.put(KEY_SENTENCE, defObj.getSentence());// get author
// 3. insert
db.insert(TableName.getTblName(), // table
null, //nullColumnHack
values); // key/value -> keys = column names/ values = column values
// 4. close
db.close();
}
public DefinitionObject getDefObj(int id, String name){
// 1. get reference to readable DB
SQLiteDatabase db = this.getReadableDatabase();
// 2. build query
Cursor cursor =
db.query(TableName.getTblName(), // a. table
COLUMNS, // b. column names
" id = ?", // c. selections
new String[] { String.valueOf(id) }, // d. selections args
null, // e. group by
null, // f. having
null, // g. order by
null); // h. limit
// 3. if we got results get the first one
if (cursor != null)
cursor.moveToFirst();
// 4. build book object
DefinitionObject defObj = new DefinitionObject();
defObj.setId(Integer.parseInt(cursor.getString(0)));
defObj.setWord(cursor.getString(1));
defObj.setDefinition(cursor.getString(2));
defObj.setExample(cursor.getString(3));
defObj.setSentence(cursor.getString(4));
Log.d("getDefObj("+id+")", defObj.toString());
cursor.close();
// 5. return book
return defObj;
}
// Get All Books
public List<DefinitionObject> getAllWords(String tblName) {
List<DefinitionObject> defObjs = new LinkedList<DefinitionObject>();
// 1. build the query
String query = "SELECT * FROM " + tblName;
// 2. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
// 3. go over each row, build book and add it to list
DefinitionObject defObj = null;
if (cursor.moveToFirst()) {
do {
defObj = new DefinitionObject();
defObj.setId(Integer.parseInt(cursor.getString(0)));
defObj.setWord(cursor.getString(1));
defObj.setDefinition(cursor.getString(2));
defObj.setExample(cursor.getString(3));
defObj.setSentence(cursor.getString(4));
// Add book to books
defObjs.add(defObj);
} while (cursor.moveToNext());
}
Log.d("getAllDefinitionObject()", defObjs.toString());
cursor.close();
// return books
return defObjs;
}
/*public List<DefinitionObject> getAllWords(String tblName) {
List<DefinitionObject> defObjs = new ArrayList<DefinitionObject>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("Select d_word from " + tblName, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
DefinitionObject defObj = cursorToDefObject(cursor);
defObjs.add(defObj);
cursor.moveToNext();
}
// Make sure to close the cursor
cursor.close();
return defObjs;
}
private DefinitionObject cursorToDefObject(Cursor cursor) {
DefinitionObject defObj = new DefinitionObject();
defObj.setId(cursor.getInt(0));
defObj.setWord(cursor.getString(1));
defObj.setDefinition(cursor.getString(2));
defObj.setExample(cursor.getString(3));
defObj.setSentence(cursor.getString(4));
return defObj;
}*/
/*public String getAllWords2(String tblName) {
String words = "Received";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("Select d_word from " + tblName, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
words+= cursor.getString(0) + "\n";
cursor.moveToNext();
}
// Make sure to close the cursor
cursor.close();
return words;
}*/
// Updating single book
public int updateDefinitionObject(DefinitionObject defObj) {
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(KEY_WORD, defObj.getWord());
values.put(KEY_DEFINITION, defObj.getDefinition());
values.put(KEY_EXAMPLE, defObj.getExample());
values.put(KEY_SENTENCE, defObj.getSentence());
// 3. updating row
int i = db.update(TableName.getTblName(), //table
values, // column/value
KEY_ID+" = ?", // selections
new String[] { String.valueOf(defObj.getId()) }); //selection args
// 4. close
db.close();
return i;
}
// Deleting single book
public void deleteDefinitionObject(DefinitionObject defObj) {
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. delete
db.delete(TableName.getTblName(),
KEY_ID+" = ?",
new String[] { String.valueOf(defObj.getId()) });
// 3. close
db.close();
Log.d("deleteBook", defObj.toString());
}
public ArrayList<String> listDictionary()
{
ArrayList<String> stringList = new ArrayList<String>();
String result="";
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table' AND name != 'android_metadata' AND name != 'sqlite_sequence' AND name != 'DefinitionTable'", null);
if (c.moveToFirst()) {
while ( !c.isAfterLast() ) {
result= c.getString(0) +"";
stringList.add(result);
//Toast.makeText(activityName.this, "Table Name=> "+c.getString(0), Toast.LENGTH_LONG).show();
c.moveToNext();
}
}
c.close();
return stringList;
}
public int countDictionary()
{
int count = 0;
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type = 'table' AND name != 'android_metadata' AND name != 'sqlite_sequence' AND name != 'DefinitionTable'", null);
if (c.moveToFirst()) {
while ( !c.isAfterLast() ) {
count = c.getCount();
c.moveToNext();
}
}
c.close();
return count;
}
//createDefinitionDIctionary
public void createDictionary(String tblname) {
//SQL statement to create ? table
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("CREATE TABLE "+ tblname +"(d_id INTEGER PRIMARY KEY AUTOINCREMENT, d_word TEXT NOT NULL,d_definition TEXT NOT NULL,d_example TEXT,d_sentece TEXT)");
}
public void deleteDictionary(String tblname)
{
//SQLiteDatabase db = this.getWritableDatabase();
//db.execSQL("DROP TABLE "+ tblname);
//Toast.makeText(getApplicationContext(), "View", Toast.LENGTH_SHORT).show();
Log.d("DELETE_TABLE", tblname);
}
}
这是我的活动名为DefinitionHomeActivity.java
package com.example.myidictionary;
import java.util.ArrayList;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class DefinitionHomeActivity extends Activity {
private MySQLiteDefinitionHelper db;
public final static String TABLENAME="com.example.myidictionary.TABLENAME";
String mesej;
ArrayList<String> listDictionary;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.definition_home);
//============================ action Bar ===========================
ActionBar actionBar = getActionBar();
actionBar.show();
actionBar.setDisplayHomeAsUpEnabled(true);//icon -> go to home
//---------------------------- action Bar ---------------------------
//=================== get mesej from other activity ============================
Intent msjIntent = getIntent();
mesej = msjIntent.getStringExtra(CreateDefinitionDictionaryActivity.MESSAGE);
if(mesej != null)
{
Toast.makeText(getApplicationContext(), "New Dictionary named " + mesej + " was created!", Toast.LENGTH_SHORT).show();
}
//-------------------- get mesej from other activity ---------------------------
//============================ Set ListView Items =============================================
db = new MySQLiteDefinitionHelper(this);
ListView mylist = (ListView)findViewById(R.id.listDictionary);
listDictionary = new ArrayList<String>();
listDictionary = db.listDictionary();
// ~~~~~~~ if list is empty ~~~~~~~
if(listDictionary.isEmpty()== true)
{
Toast.makeText(getApplicationContext(), "There is no Dictionary Exist", Toast.LENGTH_SHORT).show();
}
// ~~~~~~ if list is empty ~~~~~~
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, listDictionary);
mylist.setAdapter(adapter);
//---------------------------- Set ListView Items -----------------------------------------------
//=========================== Set On Item CLick ============================================
mylist.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
// TODO Auto-generated method stub
String selectedTable=listDictionary.get(arg2);
Toast.makeText(getApplicationContext(), "Dictionary : "+selectedTable, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(DefinitionHomeActivity.this, WordDefinitionHomeActivity.class);
intent.putExtra(TABLENAME, selectedTable);
startActivity(intent);
}
});
//----------------------------- Set On Item CLick -------------------------------------------
// ================================= Set Dialog Menu Options =========================================
final String[] option = new String[] { "Add", "View", "Delete" };
ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(this, android.R.layout.select_dialog_item, option);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select Option");
builder.setAdapter(adapter2, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{ // TODO Auto-generated method stub
switch(which){
case 0:
Toast.makeText(getApplicationContext(), "Add", Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(getApplicationContext(), "View", Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(getApplicationContext(), "Delete", Toast.LENGTH_SHORT).show();
//data = new MySQLiteDefinitionHelper(DefinitionHomeActivity.this);
db.deleteDictionary(mesej);
break;
default:
// nothing
break;
}
}
});
final AlertDialog dialog = builder.create();
// --------------------------------- Set Dialog Menu Options ---------------------------------------
// =============================== Set On Item Long CLick ======================================
mylist.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
//show dialog menu options box
dialog.show();
return true;
}
});
// ------------------------------- Set On Item Long CLick ----------------------------------------
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.definition_home, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
boolean ret=false;
if(item.getItemId() == R.id.createDictionary)
{
ret = true;
Intent intent = new Intent(this, CreateDefinitionDictionaryActivity.class);
startActivity(intent);
}
else
{
}
//Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
return ret;
}
}
这是我的logCat名为log.txt
10-17 10:46:28.171: E/Trace(3552): error opening trace file: No such file or directory (2)
10-17 10:46:39.010: E/AndroidRuntime(3552): FATAL EXCEPTION: main
10-17 10:46:39.010: E/AndroidRuntime(3552): java.lang.NullPointerException: println needs a message
10-17 10:46:39.010: E/AndroidRuntime(3552): at android.util.Log.println_native(Native Method)
10-17 10:46:39.010: E/AndroidRuntime(3552): at android.util.Log.d(Log.java:138)
10-17 10:46:39.010: E/AndroidRuntime(3552): at com.example.myidictionary.MySQLiteDefinitionHelper.deleteDictionary(MySQLiteDefinitionHelper.java:309)
10-17 10:46:39.010: E/AndroidRuntime(3552): at com.example.myidictionary.DefinitionHomeActivity$2.onClick(DefinitionHomeActivity.java:109)
10-17 10:46:39.010: E/AndroidRuntime(3552): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:941)
10-17 10:46:39.010: E/AndroidRuntime(3552): at android.widget.AdapterView.performItemClick(AdapterView.java:298)
10-17 10:46:39.010: E/AndroidRuntime(3552): at android.widget.AbsListView.performItemClick(AbsListView.java:1100)
10-17 10:46:39.010: E/AndroidRuntime(3552): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2749)
10-17 10:46:39.010: E/AndroidRuntime(3552): at android.widget.AbsListView$1.run(AbsListView.java:3423)
10-17 10:46:39.010: E/AndroidRuntime(3552): at android.os.Handler.handleCallback(Handler.java:725)
10-17 10:46:39.010: E/AndroidRuntime(3552): at android.os.Handler.dispatchMessage(Handler.java:92)
10-17 10:46:39.010: E/AndroidRuntime(3552): at android.os.Looper.loop(Looper.java:137)
10-17 10:46:39.010: E/AndroidRuntime(3552): at android.app.ActivityThread.main(ActivityThread.java:5039)
10-17 10:46:39.010: E/AndroidRuntime(3552): at java.lang.reflect.Method.invokeNative(Native Method)
10-17 10:46:39.010: E/AndroidRuntime(3552): at java.lang.reflect.Method.invoke(Method.java:511)
10-17 10:46:39.010: E/AndroidRuntime(3552): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-17 10:46:39.010: E/AndroidRuntime(3552): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-17 10:46:39.010: E/AndroidRuntime(3552): at dalvik.system.NativeStart.main(Native Method)
10-17 10:49:04.652: E/AndroidRuntime(3628): FATAL EXCEPTION: main
10-17 10:49:04.652: E/AndroidRuntime(3628): java.lang.NullPointerException: println needs a message
10-17 10:49:04.652: E/AndroidRuntime(3628): at android.util.Log.println_native(Native Method)
10-17 10:49:04.652: E/AndroidRuntime(3628): at android.util.Log.d(Log.java:138)
10-17 10:49:04.652: E/AndroidRuntime(3628): at com.example.myidictionary.MySQLiteDefinitionHelper.deleteDictionary(MySQLiteDefinitionHelper.java:309)
10-17 10:49:04.652: E/AndroidRuntime(3628): at com.example.myidictionary.DefinitionHomeActivity$2.onClick(DefinitionHomeActivity.java:109)
10-17 10:49:04.652: E/AndroidRuntime(3628): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:941)
10-17 10:49:04.652: E/AndroidRuntime(3628): at android.widget.AdapterView.performItemClick(AdapterView.java:298)
10-17 10:49:04.652: E/AndroidRuntime(3628): at android.widget.AbsListView.performItemClick(AbsListView.java:1100)
10-17 10:49:04.652: E/AndroidRuntime(3628): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2749)
10-17 10:49:04.652: E/AndroidRuntime(3628): at android.widget.AbsListView$1.run(AbsListView.java:3423)
10-17 10:49:04.652: E/AndroidRuntime(3628): at android.os.Handler.handleCallback(Handler.java:725)
10-17 10:49:04.652: E/AndroidRuntime(3628): at android.os.Handler.dispatchMessage(Handler.java:92)
10-17 10:49:04.652: E/AndroidRuntime(3628): at android.os.Looper.loop(Looper.java:137)
10-17 10:49:04.652: E/AndroidRuntime(3628): at android.app.ActivityThread.main(ActivityThread.java:5039)
10-17 10:49:04.652: E/AndroidRuntime(3628): at java.lang.reflect.Method.invokeNative(Native Method)
10-17 10:49:04.652: E/AndroidRuntime(3628): at java.lang.reflect.Method.invoke(Method.java:511)
10-17 10:49:04.652: E/AndroidRuntime(3628): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-17 10:49:04.652: E/AndroidRuntime(3628): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-17 10:49:04.652: E/AndroidRuntime(3628): at dalvik.system.NativeStart.main(Native Method)
10-17 10:49:08.083: E/Trace(3652): error opening trace file: No such file or directory (2)
答案 0 :(得分:1)
这是你可以读取堆栈跟踪的方法:
NullPointerException
android.util.Log.println_native
android.util.Log.d
您继续阅读这些行,直到找到包含您自己代码的行:
com.example.myidictionary.MySQLiteDefinitionHelper.deleteDictionary(MySQLiteDefinitionHelper.java:309)
也就是说,在MySQLiteDefinitionHelper.java
中,特别是在deleteDictionary
方法中,第309行的代码稍后会导致NullPointerException
。
public void deleteDictionary(String tblname)
{
//SQLiteDatabase db = this.getWritableDatabase();
//db.execSQL("DROP TABLE "+ tblname);
//Toast.makeText(getApplicationContext(), "View", Toast.LENGTH_SHORT).show();
Log.d("DELETE_TABLE", tblname);
}
似乎tblname
为空。这也解释了为什么你不能放弃这个桌子。
将来请不要将大块代码分成多个滚动框。
阅读logcat
中的堆栈跟踪,并在此处仅发布相关代码段,并在pastebin.com上将完整代码一起发布。
答案 1 :(得分:0)
请在此处查看我的回答。如果您花一些时间并了解其用途,它将解决Android中的所有数据库问题。