我是否需要创建/使用内容提供商

时间:2014-05-16 21:23:10

标签: android sqlite

我一直在尝试解决有关我的应用程序和应用程序服务共享SQLiteDatabase的问题;也就是说,应用程序启动的服务。该服务每隔30秒唤醒并检查数据库,然后,正如所有良好的进程应该,它在数据库完成时关闭与数据库的连接。但是,当应用程序同时运行并尝试访问数据库时,应用程序崩溃。 logcat会显示一条消息,警告我我正在尝试重新打开已关闭的数据库连接,如下所示:

  

05-16 16:48:30.796:E / AndroidRuntime(10610):   java.lang.IllegalStateException:尝试重新打开已经关闭的   object:SQLiteDatabase:/data/data/com.example.myapp/databases/eRing

勤奋的故障排除工作表明,如果我通过服务移除了数据库的关闭,一切都会好的,排序......如果我让服务周期足够长。最终,SQLiteConnectionPool会醒来并说,

  

数据库的SQLiteConnection对象   '+ data + data + com_example_myapp + databases + eRing'被泄露了!请修理   您的应用程序正确结束正在进行的事务并关闭   数据库不再需要时。

所以,我回到了绘图板,并查看了文档和教程。我注意到许多可用资源在没有讨论ContentProviders的情况下很难提及SQLiteDatabases。但是,文档说如果您打算从其他应用程序访问数据库,则只需要ContentProvider。以下是Android开发者网站的引用:

开始构建之前

在开始构建提供程序之前,请执行以下操作:

  1. 决定是否需要内容提供商。如果要提供以下一项或多项,则需要构建内容提供程序 特性:

    • 您希望向其他应用程序提供复杂的数据或文件。
    • 您希望允许用户将应用中的复杂数据复制到其他应用中。
    • 您希望使用搜索框架提供自定义搜索建议。

    如果用户完全在您自己的应用程序中,需要提供者使用SQLite数据库。

  2. 我在本文档中无法分辨的内容如下:对于App拥有服务的情况,以及Activity和Service都需要同时访问数据库,这是否需要创建ContentProvider?我很肯定我无意与其他任何东西或文档列出的任何其他方案共享此数据库。换句话说,服务和活动是否算作两个“应用程序”? Android基础知识称活动和服务为“应用程序组件”,而不是单独的“应用程序”。

    请告诉我是否需要全力以赴创建自定义ContentProvider,并且直接访问(通过SQLiteDBAdapters / Helpers)数据库是值得的。

    对于Salem:以下是Activity和Service调用的close方法。

    public class SettingsDbAdapter {
    
    private static SQLiteDatabase mDb;
    private DatabaseHelper mDbHelper;
    
    public static class DatabaseHelper extends SQLiteOpenHelper {
       //...
    
        }
    
    //...
    public void close() {
            Log.v("close()", "Close settingsdbadapter called");
            mDbHelper.close();
        }
    
    }
    
    //The following is the Services Open method:
    
    public SettingsDbAdapter openReadable() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getReadableDatabase();
    
        return this;
    }
    
    //The following is the Activities Open Method:
    public SettingsDbAdapter open() throws SQLException {
                mDb = mDbHelper.getWritableDatabase();
        if (!mDb.isWriteAheadLoggingEnabled()) {
            Log.v("SettingsDb","Trying to Enable Write Ahead Logging");
            mDb.enableWriteAheadLogging();
        }
        return this;
    }
    

1 个答案:

答案 0 :(得分:1)

只有在其他应用程序访问数据库时才需要内容提供程序,因为后者根本没有打开数据库文件的权限。

在您的情况下,问题是您在SQLiteDatabase上拥有并发访问权限。如果您编写了服务,您的活动也应该使用它。

编辑:我的评论似乎很混乱,我删除了它。我建议以下4个组成部分:

  • a BroadcastReceiver,在手机启动后,注册闹钟(通过AlarmManager),然后关闭
  • 从警报接收节拍的另一个广播接收器(警报是Android实施的服务)并检查数据
  • 显示/允许编辑数据的活动

后两者通过

访问数据
  • 提供在数据库中读取/保留业务对象的方法的服务