我有一個Android應用程序,可以將圖像上傳到服務器,然後將每個圖像的返回的URL保存在Sqlite數據庫中。Sqlite數據庫鎖定在Android中的執行器服務
要管理上傳過程,我有一個Runnables隊列。每個Runnable都上傳一張單張圖片。
如果我離線拍攝35張照片,稍後我打開應用程序,上傳過程會將35個uploadRunnables放入隊列中,然後開始上傳。
每個之後更迭從服務器我用這種方法保存相應的URL在我的SQLite數據庫響應:
public synchronized void updatePhotoUrl(String url, String Id) {
SQLiteDatabase sqldb = getWritableDatabase();
try {
sqldb.beginTransaction();
sqldb.execSQL("UPDATE photos SET url = '"+url+ "' WHERE _id ="+Id);
sqldb.setTransactionSuccessful();
Log.i("Upload","photo updated");
} catch (Exception e){
e.printStackTrace();
Log.i("Upload","Exception: "+e);
}
finally {
if (sqldb.inTransaction()) {
sqldb.endTransaction();
}
}
}
每一件事情的工作,只要我宣佈我的ExectorService
這樣的:
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
然後我Enqueue每個Runnable是這樣的:
service.execute(myUploadRunnable);
那麼完美的工作......
但後來我試圖增加線程爲10,所以我改變了我的聲明這一個。
ExecutorService service = Executors.newFixedThreadPool(10);
現在它在10個操作的區塊中進行上傳,這裏是問題出現的時間。
當它通過第3個區塊時,操作23和同一個區塊中的所有下一個區塊都會給我一個DataBaseLocked異常代碼(5),並且該URL不會寫入數據庫中。之後,第4個陣營(操作30-35)完全執行,並且沒有觸發數據庫鎖定例外。
我打電話給我的updatePhoto方法是這樣的:
PhotoDBHelper.getInstance(context).updatePhotoUrl(url,id);
PhotoDBHelper是單從SqliteOpenHelper延伸。並且該方法getInstance()
是這個:
private static PhotoDBHelper photoDBHelperInstance;
public static synchronized PhotoDBHelper getInstance(Context context) {
if (photoDBHelperInstance == null) {
photoDBHelperInstance = new PhotoDBHelper(context.getApplicationContext());
}
return photoDBHelperInstance;
}
據我所知DatabaseLocked異常不應該是可能的,如果更新方法是。這似乎是一個內存問題,因爲如果我使用較低數量的線程DatabaseLocked問題消失,至少有35個操作。而例外總是從操作23
所以我的問題是:
爲什麼增加線程10生成數據庫鎖定例外?
何時何何關閉數據庫實例? –
我不關閉它@AnuragSingh – Jofre
你應該在finally塊中關閉它。 –