在某些段落中,我遇到了sqllite错误"打开连接已打开" ...好吧,实际上我并不忙于总是关闭连接,因为我已经读过,如果操作不是很大的话,建议不要这么做......但显然并不总是这样......或者不是吗?我在这一点上感到困惑....
为了解决这个问题,我在每个使用其适配器执行数据库操作的活动中插入了此代码:
@Override
protected void onDestroy ()
{
super.onDestroy ();
mDbHelper.closeConnection ();
}
这已经解决了所有问题,而且一切都已经解决了好几个月。
现在实施其他我收到此错误:
"尝试重新打开已关闭的对象,然后关闭数据库"
一个'活动通过OnActivityForResult调用另一个活动但是"某人或某事" (我假设低级别的android)调用我的" OnDestroy" (要关闭连接)...触发我发现的错误的原因但是我不知道如何干预......我不是那个叫OnDestroy而是Android的人...它是怎么来的出?
现在(在我调用另一个活动的情况下)我已经绕过了这样的问题:
@Override
protected void onDestroy ()
{
if (! m_Modality.equalsIgnoreCase ("MYCALLBACK"))
{
mDbHelper.closeConnection ();
}
}
但我不喜欢它,我想一劳永逸地理解你是如何在这个sqlite上工作的......
如果由于有关是否已经打开的消息而不必关闭连接?
如果我关闭它,因为消息说它刚刚关闭了?
如果ANDROID调用我插入连接闭包的方法,因为我无法以明确的方式管理事物?
我希望有人能澄清我的想法......
答案 0 :(得分:0)
我建议不要尝试关闭连接/数据库,因为打开数据库资源非常昂贵(参见下面的引文)并且经常是不可靠的。可能只是在主要活动onDestroy
中关闭它,也许与使用单一的SQLiteDatabase /连接相结合。
游标虽然应该在完成时总是关闭,但太多打开会导致异常。我遵循规则,如果它们仅在方法中使用,则在方法内关闭。如果它们被活动的UI(例如Spinner,ListView等)使用,则关闭活动onDestroy
中的光标。如果它们是在循环中创建的,那么在完成它们后立即关闭它们。
因为getWritableDatabase()和getReadableDatabase()很昂贵 在数据库关闭时调用,您应该离开数据库 只要您可能需要访问它,连接就会打开。 通常,最好在onDestroy()中关闭数据库 调用Activity。 Persisting Database Connection
和
关闭连接会丢弃页面缓存,并且需要这样做 检查模式版本并重新解析整个模式 下次打开。
在大多数应用程序中,没有足够的数据库访问权限 实际上会不断重新打开数据库的开销 显。但是没有理由在您的应用中添加无用的代码。
请注意,SQLiteDatabase对象是引用计数的。因此,如果 如果您正在使用全局打开帮助程序实例,则可以保持数据库打开 使用额外的getWritableDatabase()调用,即使是所有其他调用 代码调用close()。 CL's answer
答案 1 :(得分:0)
在某些情况下,例如,你在另一个函数中传递游标结果是不可能关闭游标(你必须传递一个游标而不是null),我总是尝试创建一个'read'o'过滤器'模板函数和在最后我关闭光标但不是全部...这对于所有情况都是不可能的...这取决于我的堆栈周期,对于任何情况都不同,它是一个大应用程序,30 sqliteadapter交互......我认为它是一个错误迫使开发人员总是以不同的模式关闭和打开;如果我打开并重新关闭连接,那么sqlite会生成错误...内存?...这是复杂的应用程序中的地狱......我读了你的链接信息,现在谢谢!
这是我的代码: (我有一个界面自定义基础但不重要)
@Override
public Cursor fetchFiltro(String filtroWhere) {
Cursor mycursor =null;
try {
openConnection();
mycursor = getDatabase().query(true, getNomeTab(),
new String[] { COL_ID, COL_CODICE, COL_DESCRIZIONE,COL_PREZZOACQ,COL_PREZZOVEN, COL_CODICEUMISURA, COL_CODICEUMISURACONF, COL_QTA, COL_CODICECATEGORIA,COL_CODICEIVA, COL_FORNITORE, COL_CODICEFORNITORE, COL_ORDINEMINIMO,
COL_DATAINSERIMENTO},
filtroWhere, null, null, null, COL_DATAINSERIMENTO +" desc", null );
return mycursor;
}
catch (Exception e)
{
Toast.makeText(MyApp.getContext(), e.getMessage(),Toast.LENGTH_LONG).show();
UtiLog.WriteLogOnTop(mClassName + ".fetchFiltro() " + e.getMessage().toString(),UtiLog.ERROR);
if (!(mycursor==null)) {mycursor.close();}
return null;
}
finally
{
}
}
我致电:
public List<Articolo> dammiListaArticoliDaSqlWhere( String prm_sqlWhere )
{
List<Articolo> listaArticoli= new ArrayList<Articolo>();
Cursor cursor = fetchFiltro(prm_sqlWhere);
if( cursor != null )
{
while ( cursor.moveToNext() )
{
Articolo articolo = getArticolo(cursor);
listaArticoli.add( articolo );
}
cursor.close();
}
return listaArticoli;
}
我的openConnection()调用dbHelper类函数:
public void openConnection() throws SQLException
{
dbHelper.openConnection();
}
OpenConnection的代码:
public void openConnection() throws SQLException
{
if (getDatabase()==null)
{
setDatabase( getWritableDatabase() );
}
}
private void setDatabase(SQLiteDatabase database)
{
this.database = database;
}
它工作得很完美......只有当操作系统(主动)调用活动的OnDestroy(我必须插入closeconnection())时才会出现问题...我无法删除那个紧密连接( ),如果我在其他活动中删除它,它给我的消息“数据库已经打开”....我无法摆脱这种情况,我总是被迫手动将一些代码放到手中,从大小写到这是令人沮丧的。 再次感谢