2012-03-26 88 views
2

更新getWritableDatabase/getReadableDatabase遞歸調用

得到錯誤,當我嘗試調用從活動的方法:

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

我HAE一個名爲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(); 
     } 
} 
+0

您的前兩行代碼應該是: SQLiteDatabase db = DatabaseHelper.getWritableDatabase(); 列表 r = dbHelper.getAllAlbum(db); – bughi 2012-03-26 18:32:45

回答

4

什麼情況是,getReadableDatabase()調用的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()。

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()進行遞歸調用。

+0

我已更新我的問題,請看看 – 2012-03-26 15:00:40

0

因爲你在你的onCreate利用這一點,你不能傳遞任何參數,你可能想使一個私有方法來做到這一點,並通過在SQLiteDatabase參數,所以你總是使用相同的數據庫變量。

由於您使用的是this.getWriteableDatabase()我期望它可能指向相同的數據庫屬性,並且您多次調用它的事實可能是您的問題。我認爲這是一個設計問題,這就是爲什麼我提出了我所做的修復。

UPDATE:

要解決的NPE只是用這樣的:

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

你能告訴我你在說什麼嗎? – 2012-03-26 18:04:52

+0

另一個答案解釋得很好,但我指出你爲什麼得到一個NPE。 – 2012-03-27 01:24:08