我目前正在编写我的第一个Android应用程序,并且基于Android记事本教程基于我的大部分知识:
http://developer.android.com/resources/tutorials/notepad/notepad-ex3.html
在我的应用程序中,我在一个Activity中使用多个DBHelpers,而不是每个Cursor都由具有startManagingCursor()的活动管理。
我了解到必须正确地打开和关闭每个数据库连接:
SQLiteOpenHelper.open();
Cursor.open();
//use cursor
Cursor.close();
SQLiteOpenHelper.close();
据我所知startManagingCursor()这对你有用。但是startManagingCursor()是否也打开并关闭了SQLiteOpenHelper?
Android Notepad教程使用的是startManagingCursor(),但DBHelper永远不会关闭。为什么SQLiteOpenHelper永远不会关闭?
编辑:
这是我目前的代码。它使用一个名为mDriverDbHelper的SQLiteOpenHelper。这段代码是从教程中采用的:
私人DriverDbAdapter mDriverDbHelper;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bus_selectuser);
mDbHelper = new DbAdapter(this);
mDbHelper.open();
mDbHelper.close();
mDriverDbHelper = new DriverDbAdapter(this);
Log.w("BuerBusActivity", "opening DB connection via DbHelber now");
mDriverDbHelper.open();
fillData();
//request the screen to stay on
this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@Override
public void onRestart() {
super.onRestart();
Log.v(TAG, "onRestart");
}
@Override
public void onStart() {
super.onStart();
mDriverDbHelper.open();
Log.v(TAG, "onStart");
}
@Override
public void onResume() {
super.onResume();
Log.v(TAG, "onResume");
}
@Override
public void onPause() {
Log.v(TAG, "onPause");
super.onPause();
}
@Override
public void onStop() {
mDriverDbHelper.close();
Log.v(TAG, "onStop");
super.onStop();
}
此代码示例确实有效,但我不明白为什么。我在onCreate和onStart中调用mDriverDBHelper.open()两次。
我试图将open()和close()调用放在onPause和onResume上,但这会导致错误:
Cursor: invalid statement in fillWindow()
有人知道为什么它必须是onStart和onStop而不是onPause和onResume吗?
最终答案
本教程缺少close()方法调用。将open和close与活动生命周期结合使用的一般规则是:
在活动生命周期方法中打开SQLiteOpenHelper后,您应该在相应的对应生命周期方法中关闭它。
@Override
public void onCreate() {
....
//open SQLiteOpenHelper
onCreateHelper.open();
}
@Override
public void onStart() {
....
//open SQLiteOpenHelper
onStartHelper.open();
}
@Override
public void onResume() {
....
//open SQLiteOpenHelper
onResumeHelper.open();
}
@Override
public void onPause() {
....
//close SQLiteOpenHelper
onResumeHelper.close();
}
@Override
public void onStop() {
....
//close SQLiteOpenHelper
onStartHelper.close();
}
@Override
public void onDestroy() {
....
//close SQLiteOpenHelper
onCreateHelper.close();
}
对于Android NotePad教程,缺少onDestroy()方法,应关闭mDbHelper。
答案 0 :(得分:2)
根据startManagingCursor
文档,它只处理游标。所以我相信它对数据库连接没有任何作用,因为它可能需要在将来重新查询数据。
来自Android Developer的网站:
此方法允许活动负责管理给定的活动 Cursor基于活动生命周期的生命周期。那是, 当活动停止时,它将自动调用停用() 在给定的Cursor上,以及稍后重新启动它将调用 requery()为您服务。当活动被销毁时,所有托管游标都会被破坏 将自动关闭。
关于android记事本教程中的数据库连接关闭,我认为他们错过了在示例代码中关闭它。没什么大不了的。)
答案 1 :(得分:0)
对于它的价值,示例代码也没有处理用户点击设备的后退按钮的真实可能性。这可能会导致通过bundle extras传递空指针。为了防止样本崩溃,您可以在超级调用之后将try / catch块包装在所有内容周围,如下所示:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
try {
Bundle extras = intent.getExtras();
switch(requestCode) {
case ACTIVITY_CREATE:
String title = extras.getString(NotesDbAdapter.KEY_TITLE);
// ^^^ LATER down goes KA-BOOM !
// etc ... as in sample
} // end switch stmt
} catch (Exception e ) {
Log.d ( "onActivityResult caught exception: ", e.toString() ) ;
} // end try / catch
// ...
像C / C ++似乎 null 东西是Java中最常见的错误......
答案 2 :(得分:0)
永远不要关闭DbHelper旨在永远保持开放。
并且不要关闭getReadableDatabase()和getWritableDatabase()的结果,即使在最佳条件下也是相同的对象。
检查源代码,即使程序员不喜欢它:
private SQLiteDatabase getDatabaseLocked(boolean writable) {
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
// Darn! The user closed the database by calling mDatabase.close().
mDatabase = null;
} else if (!writable || !mDatabase.isReadOnly()) {
// The database is already open for business.
return mDatabase;
}
}
...
}
为了稳定和加快使用交易,请检查: http://tech.vg.no/2011/04/04/speeding-up-sqlite-insert-operations/