2014-02-24 77 views
2

我正在啓動一個新的Android項目,並想知道OrmLite +關於保持UI線程數據庫訪問的所有信息。Android ormlite:關閉uithread

OLD:在我上一個項目中,我爲每個insert/update/delete調用使用了ThreadPoolExecutor和一個新的AsyncTask對象,以便這些調用將在UI線程中執行。我在UI線程上做了選擇請求,只是爲了保持簡單。

新:在我的新應用程序,我想做所有的數據庫調用關閉UI線程。

在我的控制器類中使用ThreadPoolExecutors還是要走的路? (我爲每個模型對象使用一個獨立的控制器類,它爲此對象調用DAO方法並處理回調)。什麼是最佳/新選擇?使用一個處理數據庫訪問的後臺線程創建一項服務?

任何指向Android + Ormlite +關閉uid線程的最佳實踐指南,將不勝感激。

回答

6

我推薦使用LoaderManager在後臺查詢數據庫中的數據。

在加載程序的最簡單的查詢將是:

public class CustomLoader extends AsyncTaskLoader<List<? extends DbBase>> { 
    private static final String LOG_TAG = CustomLoader.class.getSimpleName(); 

    // DbBase is the parent class of all ORMLite data objects. 
    private List<? extends DbBase> mData; 

    public CustomLoader(Context context) { 
     super(context); 
    } 

    @Override 
    public List<? extends DbBase> loadInBackground() { 
     return DatabaseAdapter.getInstance().getORMLiteObjectDao().queryForAll(); 
    } 

    @Override 
    public void deliverResult(List<? extends DbBase> data) { 
     if (isReset()) { 
      return; 
     } 

     mData = data; 

     if (isStarted()) { 
      super.deliverResult(data); 
     } 
    } 

    @Override 
    protected void onStartLoading() { 
     if (mData != null) { 
      deliverResult(mData); 
     } 

     if (takeContentChanged() || mData == null) { 
      forceLoad(); 
     } 
    } 

    @Override 
    protected void onStopLoading() { 
     cancelLoad(); 
    } 

    @Override 
    protected void onReset() { 
     // Ensure the loader has been stopped. 
     onStopLoading(); 

     // At this point we can release the resources associated with 'mData'. 
     if (mData != null) { 
      mData = null; 
     } 
    } 
} 

像我一樣頗有些沉重的交易(更新/刪除/插入),我用了一個ExecutorService,創造了一個chached線程池並在執行交易執行者:

final Callable<SyncResult> transactionCall = new Callable<SyncResult>() { 
    @Override 
    public SyncResult call() throws Exception { 
     // do the sql magic 
    } 
}; 

MyApplication.execute(new Runnable() { 
    @Override 
    public void run() { 
     try { 
      TransactionManager.callInTransaction(DatabaseAdapter.getInstance().getConnectionSource(), transactionCall); 
     } catch (SQLException e) { 
      Log.e(LOG_TAG, "Error in DB transaction", e); 
     } 
    } 
}); 

由於長事務會導致鎖定的數據庫,我建議啓用「提前寫入」(要求API 11!)。

SQLiteDatabase db = mHelper.getWritableDatabase(); 
if (db != null && db.enableWriteAheadLogging()) { // requires API 11! 
    Log.d(LOG_TAG, "Write ahead enabled!"); 
    mHelper.getRuntimeExceptionDao(ORMliteDataClass.class).queryRaw("PRAGMA journal_mode = \"WAL\""); 
} 
+0

好的,非常感謝,我將實現LoaderManager模式。它是否也可以觀察數據庫的變化? 「小」提交/更新如何,運行這些異步的最佳方式是什麼?對於每一個人來說,一個asynctask對我來說似乎是一個開銷。 – Frank

+0

問題是交易比實際的操作量多。我猜一些插入/更新沒有交易是好的,他們應該沒有問題的工作。雖然讓它們在後臺線程中並不難實現。我會使用線程池而不是單獨的AsyncTasks來插入... – WarrenFaith

+0

好的,非常感謝! – Frank