我有Class LocalDatabase,其中我与SQLiteHelper
通信public class LocalDatabase extends SQLiteOpenHelper {
...
strings etc...
...
public LocalDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_LOGIN_TABLE = "CREATE TABLE " + TABLE_LOGIN + "("
+ KEY_ID + " VARCHAR(50) PRIMARY KEY,"
+ KEY_NAME + " VARCHAR(50))";
db.execSQL(CREATE_LOGIN_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_LOGIN);
onCreate(db);
}
在MainActivity中我有:
...
private LocalDatabase locDB;
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locDB = new LocalDatabase(this);
fbLogin();
}
然后在fbLogin()中我有来自FB Developers页面的函数和onComplete()方法我有这个:
@Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
UserName = user.getName();
UserId = user.getId();
try {
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
locDB.saveUser(UserId,UserName); //This gave me the exception
}catch(Exception e){
e.printStackTrace();
Toast.makeText(MainActivity.this, "Something f***ed up fataly", Toast.LENGTH_LONG).show();
}
}
}
我用ctrl + f检查了两次我的项目并搜索了“new LocalDatabase”,但我只创建了一次......
我的LOGCAT:
03-17 19:39:45.710: W/System.err(6822): java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.Hennycz.wheresmybuddy/databases/myDatabase
03-17 19:39:45.790: W/System.err(6822): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
03-17 19:39:45.790: W/System.err(6822): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1437)
03-17 19:39:45.790: W/System.err(6822): at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1339)
03-17 19:39:45.790: W/System.err(6822): at com.Hennycz.wheresmybuddy.library.LocalDatabase.saveUser(LocalDatabase.java:51)
03-17 19:39:45.790: W/System.err(6822): at com.Hennycz.wheresmybuddy.MainActivity$2$1.onCompleted(MainActivity.java:168)
03-17 19:39:45.790: W/System.err(6822): at com.facebook.Request$1.onCompleted(Request.java:270)
03-17 19:39:45.790: W/System.err(6822): at com.facebook.Request$4.run(Request.java:1670)
03-17 19:39:45.790: W/System.err(6822): at android.os.Handler.handleCallback(Handler.java:615)
03-17 19:39:45.790: W/System.err(6822): at android.os.Handler.dispatchMessage(Handler.java:92)
03-17 19:39:45.790: W/System.err(6822): at android.os.Looper.loop(Looper.java:137)
03-17 19:39:45.790: W/System.err(6822): at android.app.ActivityThread.main(ActivityThread.java:4838)
03-17 19:39:45.790: W/System.err(6822): at java.lang.reflect.Method.invokeNative(Native Method)
03-17 19:39:45.800: W/System.err(6822): at java.lang.reflect.Method.invoke(Method.java:511)
03-17 19:39:45.800: W/System.err(6822): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:874)
03-17 19:39:45.800: W/System.err(6822): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)
03-17 19:39:45.800: W/System.err(6822): at dalvik.system.NativeStart.main(Native Method)
编辑:
public void saveUser(String id, String name) {
SQLiteDatabase db = this.getWritableDatabase();
if ( checkUser(id) == 0 ) {
ContentValues values = new ContentValues();
values.put(KEY_ID, id);
values.put(KEY_NAME, name);
db.insert(TABLE_LOGIN, null, values);
db.close();
}
else {
db.close();
}
}
public int checkUser(String id) {
String countQuery = "SELECT id FROM " + TABLE_LOGIN + " WHERE id='"+id+"'";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int rowCount = cursor.getCount();
db.close();
cursor.close();
return rowCount;
}
你有任何解决方案吗?
答案 0 :(得分:0)
我猜是因为你没有关闭你的对象
尝试关闭
locDB = new LocalDatabase(this);
db.execSQL(CREATE_LOGIN_TABLE);
在每个函数的末尾
与
locDB.close();
db.close();
答案 1 :(得分:0)
我想我明白了。 getReadableDatabase
几乎总是返回相同的可写数据库。因此,在checkUser
中执行查询后,您将关闭相同的可写数据库,并在saveUser
方法中进一步使用。因为它现在肯定已经关闭了,所以你得到了美好的例外。
相反,如果您打算进一步使用并且不在checkUser
和saveUser
中关闭它,请将数据库保存为助手类中的本地变量。
您必须在考虑Activity
生命周期的情况下管理帮助程序的生命周期(打开和关闭连接对象)。例如,在onCreate
中打开帮助程序并关闭活动的onDestroy
(请记住,这不是最有效的方法)。
答案 2 :(得分:0)
saveUser
中的{p> checkUser
。在checkUser
中,您拨打getReadableDatabase
。这将返回getWritableDatabase
先前返回的相同实例。
然后,您在checkUser
中关闭此数据库,并尝试仍在saveUser
中使用它。然后在saveUser
中将其关闭,从而导致崩溃。
除非您知道自己并不需要,否则不要关闭数据库。
或者,在getWritableDatabase
返回之前,请勿在{{1}}中致电saveUser
。