我有一些与 sqlitedatabase 有关的问题。我创建了两个线程。一个用于 web 服务调用并插入数据库,第二个线程用于检索所有数据库数据。但我遇到了一些错误:
09-18 13:45:48.724: E/SQLiteDatabase(7189): android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5): , while compiling: PRAGMA journal_mode
我的代码如下:
Mainactivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dbHelper = new DbHelper(this);
setContentView(R.layout.activity_main);
try {
dbHelper.createDataBase();
} catch (IOException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
try {
Log.i("data", "webAllBrokers thread start");
GetAllBrokers(getApplicationContext());
// GetAllBrokers(getApplicationContext());
Log.i("data", "webAllBrokers thread complete");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
Log.i("data", "SelectAllData thread start.");
SelectAllData();
Log.i("data", "SelectAllData thread complete");
}
}).start();
}
private void SelectAllData() {
// TODO Auto-generated method stub
for (int i = 0; i < 100; i++) {
TblBroker.SelectAll(dbHelper);
}
}
public static void GetAllBrokers(Context context) throws IOException,
XmlPullParserException, JSONException {
// webservice call for retrieve data
String result = GetAllBrokers(context, "Admin001");
ArrayList<ModelBroker> lstBrokers = JsonParserGetAllBrokers
.parserString(result);
TblBroker.deleteAll(dbHelper);
TblBroker.insert(dbHelper, lstBrokers);
}
另一个文件是 dbhelper 文件:
DbHelper.java
public class DbHelper extends SQLiteOpenHelper {
// The Android's default system path of your application database.
private static String PACKAGENAME = "com.example.webservicedemocallbackgroundwebservice";
private static String DB_PATH = "/data/data/" + PACKAGENAME + "/databases/";
private static String DB_NAME = "GRSL_Sales_DB.sqlite";
public static int DELETED = 1;
public static int UPDATED = 2;
public static int NEW_RECORD = 3;
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
private SQLiteDatabase myDataBase;
private final Context myContext;
private String TAG = "DbHelper";
/**
* Constructor Takes and keeps a reference of the passed context in order to
* access to the application assets and resources.
*
* @param context
*/
public DbHelper(final Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own
* database.
* */
public final void createDataBase() throws IOException {
final boolean dbExist = checkDataBase();
SQLiteDatabase db_Read = null;
if (dbExist) {
// do nothing - database already exist
} else {
// By calling this method and empty database will be created into
// the default system path
// of your application so we are gonna be able to overwrite that
// database with our database.
// By calling this method and empty database will be created into
// the default system path
// of your application so we are gonna be able to overwrite that
// database with our database.
// db_Read = this.getReadableDatabase(DB_Internal);
db_Read = this.getReadableDatabase();
db_Read.close();
copyDataBase();
}
}
/**
* Restore whole database without any data
*
* @throws IOException
*/
public final void RestoreDatabase() throws IOException {
SQLiteDatabase db_Read = this.getReadableDatabase();
db_Read.close();
copyDataBase();
Log.i(TAG, "Database REstored");
}
/**
* Check if the database already exist to avoid re-copying the file each
* time you open the application.
*
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase() {
final File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}
/**
* Copies your database from your local assets-folder to the just created
* empty database in the system folder, from where it can be accessed and
* handled. This is done by transfering bytestream.
*
* @throws IOException
* */
private void copyDataBase() throws IOException {
// Open your local db as the input stream
final InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
final String outFileName = DB_PATH + DB_NAME;
// Open the empty db as the output stream
final OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
final byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public final synchronized SQLiteDatabase openDataBase() {
// Log.i("data", "data openDataBase");
// Open the database
final String myPath = DB_PATH + DB_NAME;
Log.i("database", "data openDataBase" + myDataBase);
if (myDataBase == null) {
Log.i("database", "data openDataBase");
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
myDataBase.beginTransaction();
}
return myDataBase;
}
@Override
public final synchronized void close() {
// Log.i("data", "data closeDataBase");
if (myDataBase != null) {
Log.i("database", "data closeDataBase");
myDataBase.setTransactionSuccessful();
myDataBase.endTransaction();
myDataBase.close();
myDataBase = null;
}
super.close();
}
@Override
public void onCreate(final SQLiteDatabase arg0) {
}
@Override
public void onUpgrade(final SQLiteDatabase arg0, final int arg1,
final int arg2) {
}
}
我的表格文件是:
TblBroker.java
public class TblBroker {
public static final String TABLENAME = "Broker";
public static final String ID = "ID";
public static final String SAPCODE = "SAPCode";
public static final String DISCRIPTION = "Discription";
public static final String ISACTIVE = "IsActive";
public static final String ISDELETED = "IsDeleted";
public static final String City = "City";
/**
*
* SelectAll
*
* @param dbaConnection
* @return ArrayList<ModelBroker>
*/
public static ArrayList<ModelBroker> SelectAll(DbHelper dbaConnection) {
Log.i("data", "SelectAll start");
ArrayList<ModelBroker> broker_aList = new ArrayList<ModelBroker>();
SQLiteDatabase sqldb = dbaConnection.openDataBase();
Cursor cursor = sqldb.rawQuery("Select * From " + TblBroker.TABLENAME,
null);
if (cursor != null && !cursor.isClosed())// If CursorBroker is null then
// do
// nothing
{
if (cursor.moveToFirst()) {
do {
// Set broker information in model.
ModelBroker modelBroker = new ModelBroker();
modelBroker.setID(cursor.getInt(cursor
.getColumnIndex(TblBroker.ID)));
modelBroker.setSAPCode(cursor.getString(cursor
.getColumnIndex(TblBroker.SAPCODE)));
modelBroker.setDiscription(cursor.getString(cursor
.getColumnIndex(TblBroker.DISCRIPTION)));
modelBroker.setIsDeleted(cursor.getString(cursor
.getColumnIndex(TblBroker.ISDELETED)));
modelBroker.setIsActive(cursor.getString(cursor
.getColumnIndex(TblBroker.ISACTIVE)));
modelBroker.setCity(cursor.getString(cursor
.getColumnIndex(TblBroker.City)));
broker_aList.add(modelBroker);
} while (cursor.moveToNext());
}
cursor.close();
}
Log.i("data", "SelectAll end");
dbaConnection.close();
return broker_aList;
}
public static long insert(DbHelper dbaConnection,
ArrayList<ModelBroker> listbroker) {
long id = 0;
SQLiteDatabase sqldb = dbaConnection.openDataBase();
for (int i = 0; i < listbroker.size(); i++) {
ModelBroker broker = listbroker.get(i);
ContentValues values = new ContentValues();
values.put(TblBroker.SAPCODE, broker.getSAPCode());
values.put(TblBroker.DISCRIPTION, broker.getDiscription());
values.put(TblBroker.ISACTIVE, broker.getIsActive());
values.put(TblBroker.ISDELETED, broker.getIsDeleted());
values.put(TblBroker.City, broker.getCity());
Log.i("data", "sqldb.isOpen()=" + sqldb.isOpen());
id = sqldb.insert(TblBroker.TABLENAME, null, values);
}
Log.i("data", "1 st loop end");
Log.i("data", "2nd loop start");
for (int i = 0; i < listbroker.size(); i++) {
ModelBroker broker = listbroker.get(i);
ContentValues values = new ContentValues();
values.put(TblBroker.SAPCODE, broker.getSAPCode());
values.put(TblBroker.DISCRIPTION, broker.getDiscription());
values.put(TblBroker.ISACTIVE, broker.getIsActive());
values.put(TblBroker.ISDELETED, broker.getIsDeleted());
values.put(TblBroker.City, broker.getCity());
id = sqldb.insert(TblBroker.TABLENAME, null, values);
}
Log.i("data", "2nd loop end");
// Insert
// query
// of
// SQLiteDatabase
// class.
dbaConnection.close();
return id;
}
public static int deleteAll(DbHelper dbaConnection) {
SQLiteDatabase sqldb = dbaConnection.openDataBase();
int row = sqldb.delete(TABLENAME, null, null);// Delete
sqldb.close();
sqldb = null;
return row;
}
}
请给我一些解决方案。当一个线程正在运行并打开数据库时,那时另一个线程正在打开数据库。所以请找到并发问题的解决方案。