打开strictMode后, db = new AliUserDBHelper(context).getReadableDatabase(); 这一行报错,大概就说StrictModeReadViolation 然后看到网上有人说这个读写还可能出现死锁的问题,等。 在getReadableDatabase方法的注释中说道:该操作是耗时的,不要放在主
打开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(); } } }