我有一些与 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;
    }
}
请给我一些解决方案。当一个线程正在运行并打开数据库时,那时另一个线程正在打开数据库。所以请找到并发问题的解决方案。