2013-03-07 133 views
0

我正在开发一个Android应用程序,它使用来自不同线程和进程的sqlite数据库,例如Widget和服务。数据库无法获得连接

使用Singleton模式授予的连接,我随机收到此错误:应用仍然停留在getWriteableDatabase()方法,该警告出现在日志

W/SQLiteConnectionPool(2021): The connection pool for database '/data/data/xyz' has been unable to grant a connection to thread xyz (xyz) with flags 0x1 for xyz seconds. 
W/SQLiteConnectionPool(2021): Connections: 0 active, 1 idle, 0 available. 

此错误数小时后通常发生在应用程序已关闭,我重新打开它,但没有正式的方法来重现此错误。

我试图同时使用这个方法,但没有运气:

class DB extends SQLiteOpenHelper { 

    DB databaseHelper; 
    SQLiteDatabase database; 

    /** 
    * Open a Database Helper. 
    * 
    * @param c the Context used to open the Database. 
    * @return the Database Helper. 
    */ 
    public static DB getInstance(final Context c) { 
     if (databaseHelper == null) { 
      databaseHelper = new DB(c.getApplicationContext()); 
     } 
     return databaseHelper; 
    } 

    int active_connections; 

    /** 
    * @return the Database connection to use 
    * @see closeReadableDataBase() 
    */ 
    public synchronized SQLiteDatabase getDatabase() { 
     if (database == null || !database.isOpen()) { 
      if(database!=null) database.close(); 
      database = getWritableDatabase(); 
      active_connections=0; 
      database.setLockingEnabled(false); 
      TransitionHelper.execSQL(database, "PRAGMA read_uncommitted = true;"); 
      TransitionHelper.execSQL(database, "PRAGMA synchronous=OFF;"); 
     } 
     active_connections++; 
     return database; 
    } 

    /** 
    * Closes the database connection. 
    * @see openDatabaseForRead() 
    */ 
    public synchronized void closeDatabase() { 
     active_connections--; 
     if(active_connections==0 && database!=null){ 
      database.close(); 
      database=null; 
     } 
    } 
} 

和:

class DB extends SQLiteOpenHelper { 

    DB databaseHelper; 
    SQLiteDatabase database; 

    public static DB getInstance(final Context c) { 
     if (databaseHelper == null) { 
      databaseHelper = new DB(c.getApplicationContext()); 
     } 
     return databaseHelper; 
    } 

    public synchronized SQLiteDatabase getDatabase() { 
     if (database == null || !database.isOpen()) { 
      if(database!=null) database.close(); 
      database = getWritableDatabase(); 
     } 
     return database; 
    } 

    public synchronized void closeDatabase() { 
     if(database!=null){ 
      database.close(); 
     } 
    } 
} 
+0

我认为你需要分贝的Singleton设计这个链接可以帮助 http://stackoverflow.com/questions/6905524/using-singleton-design-pattern-for- sqlitedatabase – DjHacktorReborn 2013-03-07 19:50:31

+0

考虑使用[内容提供者](http://developer.android.com/guide/topics/providers/content-providers.html)。它会节省您的时间很多... – 2013-03-07 20:12:43

+0

@DjHacktorReborn正如你可以在第二个代码块中看到的,我使用单例模式 – Spotlight 2013-03-08 13:40:49

回答

1

如果你发现自己使用来自不同进程的SQL数据库,你真的应该考虑封装它在一个内容提供商。结合加载程序,内容提供者可以方便访问跨进程,DataObservers等等。甚至还有他们创造一个API指南:Creating a Content Provider

+0

根据文档,如果所有活动构成单个应用程序的一部分,则不需要内容提供者(包括服务)。 – strange 2013-11-04 23:04:27