下面列出了怎么用android.database.sqlite.SQLiteDatabaseLockedException的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void start() {
hardAssert(!started, "SQLitePersistence double-started!");
started = true;
try {
db = opener.getWritableDatabase();
} catch (SQLiteDatabaseLockedException e) {
// TODO: Use a better exception type
throw new RuntimeException(
"Failed to gain exclusive lock to the Cloud Firestore client's offline persistence. This"
+ " generally means you are using Cloud Firestore from multiple processes in your"
+ " app. Keep in mind that multi-process Android apps execute the code in your"
+ " Application class in all processes, so you may need to avoid initializing"
+ " Cloud Firestore in your Application class. If you are intentionally using Cloud"
+ " Firestore from multiple processes, you can only enable offline persistence (that"
+ " is, call setPersistenceEnabled(true)) in one of them.",
e);
}
targetCache.start();
referenceDelegate.start(targetCache.getHighestListenSequenceNumber());
}
@Override
public SQLiteDatabase getReadableDatabase() {
int retryCounter = 0;
do {
try {
return super.getReadableDatabase();
} catch (SQLiteDatabaseLockedException dbLockException) {
retryCounter++;
if (retryCounter > GET_READABLE_DATABASE_RETRIES) {
return null;
}
try {
Thread.currentThread().sleep(GET_READABLE_DATABASE_WAIT_TIME_MS);
} catch (InterruptedException e) {
//
}
}
} while (retryCounter <= GET_READABLE_DATABASE_RETRIES);
return null;
}
private <T> T retryIfDbLocked(Producer<T> retriable, Function<Throwable, T> failureHandler) {
long startTime = monotonicClock.getTime();
do {
try {
return retriable.produce();
} catch (SQLiteDatabaseLockedException ex) {
if (monotonicClock.getTime() >= startTime + config.getCriticalSectionEnterTimeoutMs()) {
return failureHandler.apply(ex);
}
SystemClock.sleep(LOCK_RETRY_BACK_OFF_MILLIS);
}
} while (true);
}
private SQLiteDatabase openDatabase(Context context, String cacheId) {
PersistentCacheOpenHelper helper = new PersistentCacheOpenHelper(context, cacheId);
try {
// In the future we might want to consider turning off fsync writes for SQL. While this
// comes with a danger of corruption, corruptions on Android should be pretty rare and
// we can survive cases where the cache has been deleted. The performance gains should
// be measured and evaluated however.
SQLiteDatabase database = helper.getWritableDatabase();
// Set locking mode to EXCLUSIVE since we don't support multi-process apps using
// persistence.
database.rawQuery("PRAGMA locking_mode = EXCLUSIVE", null).close();
// Apparently the EXCLUSIVE lock is acquired lazily (on first read/write) but then held
// indefinitely. So do a dummy exclusive transaction to actually acquire the lock.
database.beginTransaction();
database.endTransaction();
return database;
} catch (SQLiteException e) {
// NOTE: Ideally we'd catch SQLiteDatabaseLockedException, but that requires API Level
// 11 and we support 9 so we can't.
if (e instanceof SQLiteDatabaseLockedException) {
String msg =
"Failed to gain exclusive lock to Firebase Database's offline"
+ " persistence. This generally means you are using Firebase Database from"
+ " multiple processes in your app. Keep in mind that multi-process Android"
+ " apps execute the code in your Application class in all processes, so you"
+ " may need to avoid initializing FirebaseDatabase in your Application class."
+ " If you are intentionally using Firebase Database from multiple processes,"
+ " you can only enable offline persistence (i.e. call"
+ " setPersistenceEnabled(true)) in one of them.";
throw new DatabaseException(msg, e);
} else {
throw e;
}
}
}
private void setJournalMode(String newValue) {
String value = executeForString("PRAGMA journal_mode", null, null);
if (!value.equalsIgnoreCase(newValue)) {
try {
String result = executeForString("PRAGMA journal_mode=" + newValue, null, null);
if (result.equalsIgnoreCase(newValue)) {
return;
}
// PRAGMA journal_mode silently fails and returns the original journal
// mode in some cases if the journal mode could not be changed.
} catch (SQLiteException ex) {
// This error (SQLITE_BUSY) occurs if one connection has the database
// open in WAL mode and another tries to change it to non-WAL.
if (!(ex instanceof SQLiteDatabaseLockedException)) {
throw ex;
}
}
// Because we always disable WAL mode when a database is first opened
// (even if we intend to re-enable it), we can encounter problems if
// there is another open connection to the database somewhere.
// This can happen for a variety of reasons such as an application opening
// the same database in multiple processes at the same time or if there is a
// crashing content provider service that the ActivityManager has
// removed from its registry but whose process hasn't quite died yet
// by the time it is restarted in a new process.
//
// If we don't change the journal mode, nothing really bad happens.
// In the worst case, an application that enables WAL might not actually
// get it, although it can still use connection pooling.
Log.w(TAG, "Could not change the database journal mode of '"
+ mConfiguration.label + "' from '" + value + "' to '" + newValue
+ "' because the database is locked. This usually means that "
+ "there are other open connections to the database which prevents "
+ "the database from enabling or disabling write-ahead logging mode. "
+ "Proceeding without changing the journal mode.");
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Logger.d("DataUploadService: onStartCommand");
(new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
String permissionResponse = getPermissionResponse();
if (!hasWritePermission(permissionResponse)) {
stopSelf();
}
Cursor cursor = null;
try {
if (db == null) {
return null;
}
cursor = db.query(TABLE_GROUPS,
new String[] { COLUMN_TABLE_ID, COLUMN_MSG },
COLUMN_UPLOADED + " is null AND " + COLUMN_READY_FOR_UPLOAD + " == ?",
new String[] { "1" }, null, null, null);
while (cursor.moveToNext()) {
int groupIdIndex = cursor.getColumnIndex(COLUMN_TABLE_ID);
int routeDescription = cursor.getColumnIndex(COLUMN_MSG);
generateGpxXmlFor(cursor.getString(groupIdIndex),
cursor.getString(routeDescription));
}
} catch (SQLiteDatabaseLockedException exception) {
Logger.d("DataUpload: database is locked lets try again later");
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
}).execute();
return Service.START_NOT_STICKY;
}
public boolean addForecastLocationArrayList(ArrayList<ForecastLocation> locationList) {
try {
mDB.beginTransaction();
} catch(SQLiteDatabaseLockedException sqldble) {
// This try/catch block is a bad hack. Refactor db usaage to use only one lock
// regardless of the thread
}
String insertSQL = "INSERT INTO "
+ FORECAST_LOCATIONS
+ " ("
+ KEY_FORECAST_LOCATION_ID
+ ", "
+ KEY_FORECAST_LATITUDE
+ ", "
+ KEY_FORECAST_LONGITUDE
+ ") values (?, ?, ?)";
try {
SQLiteStatement insert = mDB.compileStatement(insertSQL);
for (ForecastLocation location : locationList) {
insert.bindString(1, location.getLocationID());
insert.bindDouble(2, location.getLatitude());
insert.bindDouble(3, location.getLongitude());
insert.executeInsert();
}
mDB.setTransactionSuccessful();
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
mDB.endTransaction();
}
return true;
}
public boolean addTemperatureForecastArrayList(ArrayList<TemperatureForecast> tempForecasts) {
try {
mDB.beginTransaction();
} catch(SQLiteDatabaseLockedException sqldble) {
// This try/catch block is a bad hack. Refactor db usaage to use only one lock
// regardless of the thread
}
String insertSQL = "INSERT INTO "
+ TEMPERATURES
+ " ("
+ KEY_FORECAST_LOCATION_ID
+ ", "
+ KEY_TEMP_FORECAST_START_TIME
+ ", "
+ KEY_TEMP_FORECAST_HOUR
+ ", "
+ KEY_TEMP_FORECAST_SCALE
+ ", "
+ KEY_TEMP_FORECAST_VALUE
+ ") values (?, ?, ?, ?, ?)";
try {
SQLiteStatement insert = mDB.compileStatement(insertSQL);
for (TemperatureForecast temp : tempForecasts) {
insert.bindString(1, temp.getLocationID());
insert.bindString(2, temp.getStartTime());
insert.bindLong(3, temp.getForecastHour());
insert.bindLong(4, temp.getScale());
insert.bindDouble(5, temp.getTemperatureValue());
insert.executeInsert();
}
mDB.setTransactionSuccessful();
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
mDB.endTransaction();
}
return true;
}
public boolean addCurrentConditionArrayList(ArrayList<CbWeather> weather) {
try {
mDB.beginTransaction();
} catch(SQLiteDatabaseLockedException sqldble) {
// This try/catch block is a bad hack. Refactor db usaage to use only one lock
// regardless of the thread
}
String insertSQL = "INSERT INTO "
+ CURRENT_CONDITIONS_TABLE
+ " ("
+ KEY_LATITUDE
+ ", "
+ KEY_LONGITUDE
+ ", "
+ KEY_ALTITUDE
+ ", "
+ KEY_ACCURACY
+ ", "
+ KEY_PROVIDER
+ ", "
+ KEY_SHARING
+ ", "
+ KEY_TIME
+ ", "
+ KEY_TIMEZONE
+ ", "
+ KEY_USERID
+ ", "
+ KEY_GENERAL_CONDITION
+ ", "
+ KEY_WINDY
+ ", "
+ KEY_FOGGY
+ ", "
+ KEY_CLOUD_TYPE
+ ", "
+ KEY_PRECIPITATION_TYPE
+ ", "
+ KEY_PRECIPITATION_AMOUNT
+ ", "
+ KEY_PRECIPITATION_UNIT
+ ", "
+ KEY_THUNDERSTORM_INTENSITY
+ ", "
+ KEY_USER_COMMENT
+ ") values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try {
SQLiteStatement insert = mDB.compileStatement(insertSQL);
for (CbWeather weatherItem : weather) {
CbCurrentCondition condition = (CbCurrentCondition) weatherItem;
insert.bindDouble(1, condition.getLocation().getLatitude());
insert.bindDouble(2, condition.getLocation().getLongitude());
insert.bindDouble(3, condition.getLocation().getAltitude());
insert.bindDouble(4, condition.getLocation().getAccuracy());
insert.bindString(5, condition.getLocation().getProvider());
insert.bindString(6, condition.getSharing_policy());
insert.bindLong(7, condition.getTime());
insert.bindLong(8, condition.getTzoffset());
insert.bindString(9, condition.getUser_id());
insert.bindString(10, condition.getGeneral_condition());
insert.bindString(11, condition.getWindy());
insert.bindString(12, condition.getFog_thickness());
insert.bindString(13, condition.getCloud_type());
insert.bindString(14, condition.getPrecipitation_type());
insert.bindDouble(15, condition.getPrecipitation_amount());
insert.bindString(16, condition.getPrecipitation_unit());
insert.bindString(17, condition.getThunderstorm_intensity());
insert.bindString(18, condition.getUser_comment());
insert.executeInsert();
}
mDB.setTransactionSuccessful();
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
mDB.endTransaction();
}
return true;
}