2014-02-09 21 views
0

當我嘗試插入數據庫中的一些價值觀,我得到以下警告如何管理嚴格的政策警告,同時訪問數據庫

android.os.StrictMode$StrictModeDiskReadViolation: policy=2079 violation=2 

探索在此之後,我才知道,

StrictMode最常用於捕獲應用程序主線程上的意外磁盤或網絡 訪問,其中UI操作接收到 併發生動畫。保持磁盤和網絡 操作關閉主線程進行的更加順暢

所以現在我使用的是Thread,我也執行該數據庫中插入和刪除如下

new Thread(new Runnable() { 
      public void run() { 


       //insert data into database 



      } 
      }).start(); 

但問題每次都在某處或其他地方,我無法創建線程來執行小型小操作。 那麼是否有任何統一或通用的方式來執行此類數據庫任務? 此外,我是否需要跟蹤我創建的這個匿名線程?

回答

0

的問題是每次某處或其他地方,我不能創建線程來執行小小的操作

磁盤I/O和網絡I/O不是「小小行動」從主應用程序線程的立場。

那麼是否有任何統一或通用的方式來執行此類數據庫任務?

使用執行數據庫操作的ThreadAsyncTaskIntentService,等等,這取決於你的需求。

此外,我是否需要跟蹤我正在創建的這個匿名線程?

這取決於線程的性質。

考慮到你的代碼片段,如果//insert data into database就是這麼做的,雖然在主應用程序線程上執行需要很長的時間,但它仍應該以毫秒或秒來完成。此時,線程將自行終止。只要你沒有做任何可能導致線程無限期運行的事情,你可能不需要擔心線程本身。

另一種方法是讓單個線程不斷運行,阻塞工作隊列。這可能是HandlerThread,或者它可能是一個常規Thread使用類似LinkedBlockingQueue的東西。然後,當其他應用程序想要執行一些I/O時,它會向該工作隊列發佈消息,從而導致線程去完成這項工作。在這種情況下,當你完成這個任務時,你需要確保你擺脫了這個線程,因爲它被設計爲永遠運行,等待更多的工作。不幸的是,確定何時完成它可能很困難。這就是爲什麼爲單個事務生成短命的一次性線程(例如,一組數據庫插入)往往更簡單的原因之一。

+0

我不知道關於'LinkedBlockingQueue'用'HandlerThread'所以是蠻好用的吧'Handler'和使用'SendMessage'發送數據時,只要我想執行插入或刪除數據庫? – Hunt

+0

@Hunt:默認的'Handler'綁定到主應用程序線程,因此發送給它的消息在主應用程序線程上處理,這不是您想要的。一個'HandlerThread'是一個獨立的線程,帶有一個附加的'Handler',並且*'Handler'將在這個單獨的線程上處理它的消息。 – CommonsWare

+0

你有任何它的例子嗎? 'LinkedBlockingQueue'或'HandlerThread' – Hunt

0

CommonsWare的答案是正確的。另一種解決方案是ASyncQueryHandlerhttp://developer.android.com/reference/android/content/AsyncQueryHandler.html

你可以打電話,startInsert做你插入異步,並覆蓋onInsertComplete如果你想讓它完成時得到通知。

A「簡單」的例子就是在這裏ExpandableList2

+0

請注意,這隻適用於查詢,就像使用具有「ContentProvider」的'CursorLoader'一樣。這些減少了你自己分叉的線程數量,儘管線程仍然在分支之下。 – CommonsWare