2010-08-30 114 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