打開strictMode後,
db = new AliUserDBHelper(context).getReadableDatabase(); 這一行報錯,大概就說StrictModeReadViolation
然後看到網上有人說這個讀寫還可能出現死鎖的問題,等。
在getReadableDatabase方法的註釋中說道:該操作是耗時的,不要放在主線程裏,也不要在ContentProvider的onCreate方法中調用。
{@link #getWritableDatabase}, this method may
* take a long time to return, so you should not call it from the
* application main thread, including from
* {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.
那創建數據庫的操作應該放在哪裏呢?難到真是要開個線程,再傳個handler給main/ui thread?
安卓sdk的demo有一個NotePad,就是在ContentProvider的onCreate方法中開的數據庫
這個demo肯定是不行的,正確的做法如下:
簡單講,就是DBHelper的構造器只new自己,不要開數據庫,不要調用getReadableDatabase的操作,
把getReadableDatabase的操作放在具體的insert,remove,delete等的方法體中,這些方法是可以異步調用的,而且往往應該異步調用
舉個栗子
**DataSQLHelper .class**
public class DataSQLHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "test.db";
private static final int DATABASE_VERSION = 1;
public DataSQLHelper (Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table " + TABLE + "( " + BaseColumns._ID
+ " integer primary key autoincrement, " + ID + " text, "
+ PASSWORD + " text, " + ACTIVE + " text, " + STATUS
+ " text);";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion >= newVersion)
return;
String sql = null;
if (oldVersion == 1)
sql = "alter table " + TABLE + " add note text;";
if (oldVersion == 2)
sql = "";
if (sql != null)
db.execSQL(sql);
}
@Override
public synchronized void close() {
super.close();
}
}
// ***Test_Java .java***
public class Test_Java extends Activity {
DataSQLHelper helData;
SQLiteDatabase db;
Cursor cursor;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
helData= new DataSQLHelper(this);
cursor = getData();
startManagingCursor(cursor);
setContentView(R.layout.view);
} catch (Exception ex) {
}
} // onCreate Ends
//因爲這裏只有一個方法,如果開多個方法的話,那麼是不是要判斷db是否爲空,以及是否打開,在調用db = helData.getReadableDatabase()方法?
private Cursor getData() {
try {
<strong>db = helData.getReadableDatabase();//<span style="color:#ff6666;">這裏是不是要if(db == null || db.isOpen() == false)</span></strong>
cursor = db.query(DataSQLHelper.TABLE, null, null,
null, null, null, null);
startManagingCursor(cursor);
return cursor;
} catch (Exception ex) {
System.out.println("Exception Occured : " + ex.toString());
return null;
}
}
<strong>//這裏必須要關閉cursor,關閉db,關閉helper,否則報dbexception異常
</strong>@Override
protected void onDestroy() {
System.out.println("onDestroy");
super.onDestroy();
if (db!=null){
db.close();
}
if (cursor!=null){
cursor.close();
}
if ( helData!=null){
helData.close();
}
}
}