2

我是 StackOverFlow 和 Android 开发的新手。实际上,这是我开发安卓应用程序的第一个真实项目。

从我的 MySQLiteDefinitionHelper 调用名为 deleteDictionary() 的函数或方法时遇到问题。我通过使用 onItemLongCLick 触发它从我的 DefinitionHomeActivity 调用该方法,然后会弹出一个对话框菜单来选择添加、查看和删除选项。一旦用户单击删除选项,该方法将真正被触发。

一开始,我想用这个方法在数据库中删除一个表。但是,发生错误并导致应用程序在触发事件时停止。

我认为这可能与数据库错误有关。然后我将函数更改为执行一些 Log.d() 并注释所有具有数据库操作的代码,但仍然出现相同的错误。

我参考了互联网上的许多资源并更改了一些我的编码,但仍然没有改变任何东西。我希望有人可以帮助我并解释实际发生的事情。谢谢你。

这是我的名为 DefinitionObject.java 的 Bean 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)
4

2 回答 2

1

这是读取堆栈跟踪的方式:

  • ANullPointerException被扔了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 上一次性发布完整代码。

于 2013-10-18T05:28:09.513 回答
0

在这里查看我的答案。如果您花一些时间并了解其用法,它将解决您在 Android 中的所有数据库问题。

填充 SQLite 数据库

于 2013-10-18T05:08:03.163 回答