在多个 Android Activity 之间共享 sqlite 数据库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1556930/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:15:23  来源:igfitidea点击:

Sharing sqlite database between multiple Android Activities

androidsqlite

提问by John in MD

Can two or more Android Activities open an sqlite3 database for write?

两个或多个 Android Activity 可以打开一个 sqlite3 数据库进行写入吗?

I have two Activities that need to insert data into the same sqlite database. When the second Activity calls SQLiteOpenHelper.getWriteableDatabase()an IllegalStateException is thrown with the message "SQLiteDatabase created and never closed".

我有两个活动需要将数据插入同一个 sqlite 数据库。当第二个 Activity 调用SQLiteOpenHelper.getWriteableDatabase()IllegalStateException 时,会抛出消息“ SQLiteDatabase created and never closed”。

I've been able to avoid the Exception by making my database object a singleton but I'm thinking there must be a better way.

我已经能够通过使我的数据库对象成为单例来避免异常,但我认为必须有更好的方法。

Thanks,

谢谢,

John

约翰

采纳答案by Jeremy Logan

There's never really more than one Activity running at a time. The easy way to fix this would be to have the first Activity close it's connection before starting the second Activity. You can do this in the onPause() then reopen it in the onResume(). Something like this (very psuedo-code):

一次运行的活动永远不会超过一个。解决这个问题的简单方法是在启动第二个活动之前让第一个活动关闭它的连接。您可以在 onPause() 中执行此操作,然后在 onResume() 中重新打开它。像这样的东西(非常伪代码):

MyActivity {
    OnResume()
        open connection to database
    OnPause()
        close connection to database
}

This way you're never trying to have more than one connection at a time and the connection is always available.

通过这种方式,您永远不会尝试一次拥有多个连接,并且该连接始终可用。

回答by cdonner

I also have multiple Activities and each Activity opens its own database connection. I keep the main Activity alive while I start other activities, and I call finish() on the child activities when I no longer need them.

我也有多个活动,每个活动打开自己的数据库连接。当我开始其他活动时,我保持主要活动处于活动状态,当我不再需要它们时,我会在子活动上调用 finish() 。

What I am seeing is that a child Activity can successfully open a connection and query data while the main Actitity is still holding on to its DBAdapter. When the child Activity ends, the main Activity requeries any cursors that are open. This seems to happen automatically.

我所看到的是,子活动可以成功打开连接并查询数据,而主活动仍保留其 DBAdapter。当子 Activity 结束时,主 Activity 会重新查询所有打开的游标。这似乎是自动发生的。

However, after clicking around on the user interface for a while, which causes my app to start and finish Activities, I will eventually get the exception:

但是,在用户界面上单击一段时间后,导致我的应用程序启动和完成活动,我最终会得到异常:

ERROR/Database(17657): Leak found
ERROR/Database(17657): java.lang.IllegalStateException:
      /data/data/yourpackage/databases/yourdatabase 
      SQLiteDatabase created and never closed
ERROR/Database(17657): at android.database.sqlite.SQLiteDatabase.<init>
     (SQLiteDatabase.java:1694)

The exception is not from the Activity that is currently in the foreground, but from one that was finished a while ago. So, what happens is that the garbage collector is cleaning up and finding the open database connection. This does not affect the app - it continues to work fine and all queries from the foreground Activity return data.

异常不是来自当前处于前台的 Activity,而是来自不久前完成的 Activity。所以,发生的事情是垃圾收集器正在清理并找到打开的数据库连接。这不会影响应用程序 - 它继续正常工作并且来自前台活动的所有查询返回数据。

The solution is simply to close the connection in the child Activity. The onDestroy() event is the right place to do that:

解决方法很简单,就是关闭子Activity中的连接。onDestroy() 事件是执行此操作的正确位置:

@Override    
protected void onDestroy() {        
    super.onDestroy();
    myAdapter.close();
}

Since I put this in all my child Activities, I no longer get the exception.

因为我把它放在我所有的孩子活动中,我不再有例外。

回答by Indrajit Banerjee

What I would do is define the database in a superclass which is AppCompatActivity if all the activities extend this class, or define it in Activity class which is inherited for all activities.

如果所有活动都扩展了此类,我将在 AppCompatActivity 超类中定义数据库,或者在为所有活动继承的 Activity 类中定义它。