Android:从资产文件夹复制数据库,但只得到一个空文件
伙计们,我在将数据库从本地资产文件夹复制到 /data/data/package_name/databases 目录时遇到问题。当我使用 http://www. iredesign.com/blog/using-your-own-sqlite-database-in-android-applications/教程来做到这一点,我只能得到一个空文件。
我引用了copyDataBase()方法的部分,没有区别。每次应用程序启动时,它都会创建目录和空数据库。那么有什么方法可以让 copyDataBase() 工作吗?
非常感谢!!
guys, I have the problem when copying database from local assets folder to /data/data/package_name/databases directory. As I use the http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/ tutorial to do it, I can only get an empty file.
I quoted the part of copyDataBase() method and there is no difference. Every time the app start, it will create the directory and empty database. So is there any way to make the copyDataBase() work?
Thank you very much!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
为什么不从资产中复制?这样做是完全正常的。但你不能在 onCreate 中执行此操作,此时已经创建了一个空数据库。你需要提前做。我通常在 getWriteableDatabase 的重写中执行此操作,例如
Why wouldn't you copy from assets? It's perfectly normal to do so. But you can't do it in the onCreate, at that point an empty database is already created. You need to do it prior. I usually do it in an override of getWriteableDatabase, something like
我不知道它是否仍然有用,但这里是其他来这里查看遮阳篷的人的解决方案。您使用的代码适用于大多数手机,一些较旧的手机与 getReadableDatabase() 函数有不同的行为。因此,您的问题不在于 copyDataBase 函数,而在于 createDataBase 函数。
在 createDataBase() 中有以下检查;
这将检查是否已经存在具有所提供名称的数据库,如果没有,则创建一个空数据库,以便可以用资产文件夹中的数据库覆盖它。在较新的设备上,此功能可以完美运行,但在某些设备上,此功能不起作用。主要是旧设备。我不知道到底为什么,但 getReadableDatabase() 函数似乎不仅获取数据库而且还打开它。如果您随后从资产文件夹中复制数据库,它仍然具有指向空数据库的指针,并且您将收到表不存在错误。
因此,为了使其在所有设备上都能工作,您应该将其修改为以下几行:
即使数据库在检查中打开,此后也会关闭,不会再给您带来任何麻烦。
I don't know if it is still usefull but here is the solution for others that get here to see the awnser. The code you used, works for most phones, some older phones have different behaviour with the getReadableDatabase() function. Your problem therefore is not in the copyDataBase function but in the createDataBase function.
in createDataBase() there is the following check;
This checks if there is already a database with the provided name and if not creates an empty database such that it can be overwritten with the one in the assets folder. On newer devices this works flawlessly but there are some devices on which this doesn't work. Mainly older devices. I do not know exactly why, but it seems like the getReadableDatabase() function not only gets the database but also opens it. If you then copy the database from the assets folder over it, it still has the pointer to an empty database and you will get table does not exist errors.
So in order to make it work on all devices you should modify it to the following lines:
Even if the database is opened in the check, it is closed thereafter and it will not give you any more trouble.
我不会从如果您的数据库中需要一些标准条目,您可以使用assets
文件夹中复制任何数据库。INSERT
添加它们在您的onCreate()
方法中。更新:由于这因错误而被否决(这有点正确)并且我无法删除它,所以这里有一个小更新。
我想说这取决于您想要添加到数据库中的标准条目数量。如果只是一两个,那么运输打包的数据库可能不值得。
无论如何,一些应用程序带有相当大的数据库(例如,食谱集合)。显然你不能在代码中添加所有这些。
onCreate()
中。为了使后者正常工作,您需要将数据库文件从
assets/
复制到您的应用程序文件夹。有一个很好的库可以为您处理这个问题: android-sqlite-asset-helperI wouldn't copy any database form theIf you need some standard entry's in your Database, you can add them usingassets
-folder.INSERT
s in youronCreate()
-method.Update: Since this is getting down-voted for being wrong (which is kinda right) and I can't delete it, here is a little update.
I'd say it depends upon how many standard entries you want to add to your database. If it's just one or two, shipping a packed DB might not be worth it.
Anyways, some apps come with rather large databases (for example, a recipe collection). You can obviously not add all these in code.
onCreate()
.For the later to work, you'll need to copy the database file from
assets/
to your app-folder. There is a nice library to handle that for you: android-sqlite-asset-helper上面的例子对我来说是这样的:
否则我会得到一个 IO 错误;
at the right above example worked for me this way:
otherwise i got an IO error;
这是我使用的简单方便的代码:
}
并在代码中使用:
Here is the simple and convenient code which I use:
}
And using in code: