2010-08-30 99 views
5

我有一個關於數據訪問的通用Android設計問題。我的應用程序中有很多活動需要訪問SQLite數據庫。爲了在一個地方包裝所有的數據訪問邏輯,我創建了一個DataseHandler類來處理所有的數據訪問邏輯。該類負責構建子句的位置,調用數據庫並詢問生成的遊標以檢索查詢結果並將它們返回給調用者。此類的目的是將所有數據訪問代碼封裝在一個地方,以便可以輕鬆管理和維護,而不是將數據訪問邏輯分散在所有活動中。每個需要訪問數據庫的活動都會創建一個這個DatabaseHandler類的實例,並將其傳遞給android.content.Context。然後,DatabaseHandler類使用此Context對象調用基礎內容提供者,如下所示:context_i.getContentResolver()。query(...)。Android數據庫訪問設計方法

我的數據訪問邏輯(具體的遊標處理邏輯)不在活動中,因此我無法管理遊標生命週期,因此可能會出現內存泄漏。

我的問題如下 -

  1. 我如何(如果它甚至有可能)從活動外管理的遊標的生命週期?
  2. 每個活動是否應該創建此數據處理程序類的實例並將上下文的實例傳遞給它?也許我的設計方法是錯誤的,我應該將這些數據訪問函數公開爲以調用活動的實例作爲參數的靜態方法。這樣我可以執行託管查詢並讓活動管理光標生命週期?

我真的很想了解最好的方法。任何意見,將不勝感激

回答

2

的標準方法:
一般來說,如果你有自己寫的ContentProvider的,你在你的manifest.xml文件正確註冊它,你可以(例如)

@Override 
public void onCreate(Bundle savedInstanceState){ 
    ... 

    if (getIntent().getData() == null) { 
     getIntent().setData(MyMetaData.CONTENT_URI); 
    } 

    Cursor cursor = managedQuery(getIntent().getData(), null, null, null, null); 

    //create an appropriate adapter and bind it to the UI 
    ... 
} 

這會自動調用ContentProvider的是能夠處理給定的內容URI,給你註冊在manifest.xml文件中像

<provider android:name="MyContentProvider" android:authorities="com.mycompany.contentprovider.MyContentProvider" /> 

我總是建議人們看看Notepad example,以瞭解ContentProvider應該如何實現。

替代方案:
一般來說,如果你只是需要你的活動範圍內訪問您的數據我會堅持的「標準做法」使用ContentProviders,其中順便說一句。可能使它成爲最靈活的解決方案。
如果您的解決方案需要來訪問也沒有「managedQuery」metods的非Activity類的數據,那麼您可以自己實現某種DAO(數據訪問對象)類。一個例子可能是

public class MyDataDao implements IMyDataDao { 
    private ContentResolver contentResolver; 

    public MyDataDao(ContentResolver contentResolver){ 
     this.contentResolver = contentResolver; 
    } 


    @Override 
    public MyDataObject readMyDataObjectById(long id){ 
     MyDataObject result = null; 

     Cursor myDataObjectCursor = contentResolver.query(...); 
     if(myDataObjectCursor != null && myDataObjectCursor.moveToFirst()){ 
     result = new MyDataObject(); 
     result.setTitle(myDataObjectCursor.get..); 
     ... 
     } 
     myDataObjectCursor.close(); 

     return result; 
    } 
} 

這也可以。然後調用你的DAO

IMyDataDao dao = new MyDataDao(context.getContentResolver()); 
MyDataObject anObj = dao.readMyDataObjectById(10); 
... 

。希望你指出了正確的方向:)

+0

謝謝您的回答樹裏,但我想你也許誤解了問題。我已經有了一個內容提供者和一個數據訪問對象。 (我從上面稍微修改了一些問題,使它們更清晰一些)。 1.我如何(如果它甚至可能的話)從Activity外部(在我的數據訪問對象內)管理遊標生命週期? 2.每個活動是否應該創建此數據訪問對象的實例並將上下文的實例傳遞給它?也許DAO應該公開靜態方法,以便每個活動不需要創建數據訪問對象的實例? – Brian 2010-08-31 08:09:59

+0

我提供了一個處理活動外光標的例子,即在你的DAO對象中。當然,你應該考慮創建你的dao對象的單例實例,如果你關心的話,靜態的實例通常對單元測試不好。 – Juri 2010-08-31 18:37:59