getWritableDatabase / getReadableDatabase以递归方式调用

时间:2012-03-26 00:25:54

标签: android sqlite

更新

当我尝试从Activity调用方法时出现错误:

SQLiteDatabase db = null;
List<Album> r = dbHelper.getAllAlbum(db);  

在我的dbHelper中,我有一个名为getAllAlbum

的方法
// Getting All Contacts
public List<Album> getAllAlbum(SQLiteDatabase db) {
List<Album> rec = new ArrayList<Album>();
// Select All Query
String selectQuery = "SELECT  * FROM " + KEY_TABLE;

Cursor cursor = db.rawQuery(selectQuery, null);

// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
    Album r = new Album();
    r.setID(Integer.parseInt(cursor.getString(0)));
    r.setAlbumID(cursor.getString(1));
      ...............
      ...............
    rec.add(r);
} while (cursor.moveToNext());
}
// return contact list
return rec;
}

03-25 20:12:48.995: E/AndroidRuntime(27297): FATAL EXCEPTION: main
03-25 20:12:48.995: E/AndroidRuntime(27297): java.lang.RuntimeException: Unable to start activity ComponentInfo{net.website.Media_Player_Activity}: java.lang.NullPointerException
03-25 20:12:48.995: E/AndroidRuntime(27297):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at android.os.Looper.loop(Looper.java:123)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at android.app.ActivityThread.main(ActivityThread.java:3683)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at java.lang.reflect.Method.invokeNative(Native Method)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at java.lang.reflect.Method.invoke(Method.java:507)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-25 20:12:48.995: E/AndroidRuntime(27297):    at dalvik.system.NativeStart.main(Native Method)
03-25 20:12:48.995: E/AndroidRuntime(27297): Caused by: java.lang.NullPointerException

END UPDATE

我之前搜索过这个问题但是没有解决我的问题所以最后发布了我的问题......

我想在sqlhelper类中插入几行,当我得到以下错误时...

logcat的:

03-25 05:34:06.725: E/AndroidRuntime(17465): java.lang.RuntimeException: Unable to start activity ComponentInfo{net.website.Media_Player_Activity}: java.lang.IllegalStateException: getWritableDatabase called recursively
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.os.Looper.loop(Looper.java:123)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.app.ActivityThread.main(ActivityThread.java:3683)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at java.lang.reflect.Method.invokeNative(Native Method)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at java.lang.reflect.Method.invoke(Method.java:507)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at dalvik.system.NativeStart.main(Native Method)
03-25 05:34:06.725: E/AndroidRuntime(17465): Caused by: java.lang.IllegalStateException: getWritableDatabase called recursively
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:101)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at net.issoa.db.DatabaseHelper.getReciterCount1(DatabaseHelper.java:120)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at net.issoa.db.DatabaseHelper.onCreate(DatabaseHelper.java:80)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:126)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at net.issoa.db.DatabaseHelper.getAllReciterObj(DatabaseHelper.java:144)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at net.issoa.Media_Player_Activity.doInBackground(Media_Player_Activity.java:535)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at net.issoa.Media_Player_Activity.onCreate(Media_Player_Activity.java:106)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-25 05:34:06.725: E/AndroidRuntime(17465):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)



public class DatabaseHelper extends SQLiteOpenHelper {

public DatabaseHelper(Context context) {
        super(context, KEY_DB_NAME, null, KEY_DATABASE_VERSION); 
    }

@Override
    public void onCreate(SQLiteDatabase db) { 

        db.execSQL("CREATE TABLE " + KEY_TABLE + "(" + 
                KEY_ID + " INTEGER PRIMARY KEY, " +
                KEY_ALBUM_ID + " TEXT, " + 
                ");"); 
        //Inserts pre-defined departments 
        if (getAlbumCount() == 0)
        {
            InsertAlbum();
        }
    }

    int getAlbumCount()
    {
        SQLiteDatabase db=this.getReadableDatabase();
        Cursor cur= db.rawQuery("Select * from "+ KEY_TABLE, null);
        int x= cur.getCount();
        cur.close();
        return x;
    }

        void InsertAlbum()
    { 
         ContentValues cv = new ContentValues(); 
             cv.put(KEY_ALBUM_ID, KEY_ALBUM_ID_VALUE);
             ................
             SQLiteDatabase db = this.getWritableDatabase();
        db.insert(KEY_TABLE, null, cv);
        db.close();
        } 
}

2 个答案:

答案 0 :(得分:4)

getReadableDatabase()调用onCreate()调用onCreate()调用getAlbumCount调用getReadableDatabase()调用onCreate()...你可以看到它的去向。

简单的解决方法是将db作为参数发送到getAlbumCount(),就像这样

public class DatabaseHelper extends SQLiteOpenHelper {

public DatabaseHelper(Context context) {
        super(context, KEY_DB_NAME, null, KEY_DATABASE_VERSION); 
    }

@Override
    public void onCreate(SQLiteDatabase db) { 

        db.execSQL("CREATE TABLE " + KEY_TABLE + "(" + 
                KEY_ID + " INTEGER PRIMARY KEY, " +
                KEY_ALBUM_ID + " TEXT, " + 
                ");"); 
        //Inserts pre-defined departments 
        if (getAlbumCount(db) == 0)
        {
            InsertAlbum(db);
        }
    }

    int getAlbumCount(SQLiteDatabase db)
    {

        Cursor cur= db.rawQuery("Select * from "+ KEY_TABLE, null);
        int x= cur.getCount();
        cur.close();
        return x;
    }

        void InsertAlbum(SQLiteDatabase db)
    { 
         ContentValues cv = new ContentValues(); 
             cv.put(KEY_ALBUM_ID, KEY_ALBUM_ID_VALUE);
             ................

        db.insert(KEY_TABLE, null, cv);
        db.close();
        } 
}

响应更新:由于您正在向getAllAlbum()发送null,因此您将获得空指针异常。

SQLiteDatabase db = dbHelper.getWritableDatabse(db);
List<Album> r = dbHelper.getAllAlbum(db);  

更简洁的解决方案是重载这样的getAllAlbum()方法。

public class DatabaseHelper extends SQLiteOpenHelper {

     public List<Album> getAllAlbum() {
     //never ever call this method from within onCreate()
     return getAllAblum(this.getWritableDatabase());
     }

     private List<Album> getAllAlbum(SQLiteDatabase db) {
     // get results here
     //only call this method from within the class
     }

}

如果您需要外部和内部访问,您也可以使用以前的方法。 这样你就可以从外面调用没有参数的getAllAlbum(),并避免对onCreate()进行递归调用。

答案 1 :(得分:0)

由于您在onCreate中使用此功能并且未传递任何参数,因此您可能需要创建一个私有方法来执行此操作,并传入SQLiteDatabase参数,因此您始终使用相同的数据库变量。

由于您使用this.getWriteableDatabase()我希望它可能指向相同的数据库属性,并且您多次调用它可能是您的问题。我认为这是一个设计问题,这就是我提出修复的原因。

<强>更新

要修复NPE,只需使用:

SQLiteDatabase db = this.getReadableDatabase();;
List<Album> r = dbHelper.getAllAlbum(db);