2017-02-10 48 views
0

我有一個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生成數據庫鎖定例外?

+0

何時何何關閉數據庫實例? –

+0

我不關閉它@AnuragSingh – Jofre

+0

你應該在finally塊中關閉它。 –

回答

0

我有一個SQLiteDatabase對象的重複實例。

SQLiteDatabase myDB = getReadableDatabase(); 

將線程增加到10會增加對對象同時操作的可能性。

刪除重複並使用相同的SQLiteDatabase對象解決了問題。