我正在从restful服务器上提取大量json。我使用来自google的GSON库来遍历这个json,它工作得很好。现在,我想将所有json对象保存在sqlite中,但是我想使用一个事务同时添加所有这些对象。如果没有在一个数据结构中准备好所有的对象,这是很困难的。由于我一次遍历json一个对象,我想我必须将其存储在数据结构中,比如数组或散列图,然后使用数据库事务来快速执行插入。然而..。将大量数据(包括20万json对象)存储到内存中的结构中可以占用大量的内存,而且可能也会耗尽。什么是最好的方式,让所有的json对象进入我的sqlite,同时又不消耗大量的记忆,换句话说,存储和插入的方式,允许大量的回收。
发布于 2014-10-26 21:21:47
我知道这并不是在Android中处理大型json输入的最佳实现,但它确实工作得很好。
所以我的解决方案很简单:
在解析JSON代码时,使用准备语句和db事务来执行插入。因此,简而言之,一旦解析了JSON对象,获取该信息,使用准备语句和db事务将其插入到db中,然后转到下一个对象。
我刚刚通过JSON和GSON从远程服务器中提取了210 000行,每个字段有23个字段(即460万个值),同时将所有这些值插入到设备上的SQLite3 db中,时间不到5分钟,没有浪费任何内存。每一次解析/插入迭代都使用相同的内存量,并在下一次迭代中清理。
所以是的,有解决办法。显然,对于具有1000多条记录的商业应用程序或表来说,这不是最好的解决方案,但它对我的情况非常有用。
发布于 2014-10-26 17:03:24
如果您想在一个独特的时刻添加大量的数据,那么无论如何都需要大量的内存。20万个大型JSON对象占用一定的内存,您将而不是更改它。
您可以保持这种行为,但我认为这不是一个很好的解决方案,因为您在Android设备和服务器上都会产生巨大的内存消耗。如果您按部分接收数据并以这种方式添加它们,情况会更好:但是您需要控制服务器代码。
如果您是绝对,您必须保持这种行为,也许您应该同时接收所有数据,在一个巨大的JSON对象上解析它们,然后进行多个事务处理。检查每个事务是否被正确执行,如果没有,则将数据库恢复到一个良好的状态。这是个很糟糕的方法,IMHO.但我不知道你所有的限制。
完成:避免一次收到大量数据。最好提出多个请求,以获得部分数据集。它将使您的应用程序不再依赖于网络:如果您在网络上松开2秒,可能只有一个请求会失败。因此,您必须只重试一个请求,并再次收到一小部分数据。只有一个巨大的请求:如果你失去了网络,你将不得不重试整个请求.
发布于 2015-08-21 10:12:27
您是否曾经尝试过在Android数据库(SQLite)中添加大量数据(在我的例子中,我的意思是2600行数据)?
如果是这样的话,你很可能会走和我一样的路。
我尝试了一个正常的InsertStatement,这是慢的方式(10秒)。在我的模拟器里)。然后我尝试了PreparedStatements。时机更好,但仍然不能接受。(6秒)在写了几个小时令人沮丧的代码之后,我终于找到了一个很好的解决方案。
Android为InsertHelper提供了一种快速的批量插入方式。
要概述性能(在一台糟糕的计算机上使用仿真器测量,尝试插入2600行数据):
Insert-Statement
10 seconds
Prepared-Statements
6 seconds
InsertHelper
320 ms您可以通过临时禁用线程锁来加快插入速度。这将获得大约30 %的性能。但是,重要的是要确保每次只有一个线程在插入数据时使用数据库,因为它不再是线程安全了。
public void fillDatabase(HashMap<String, int[]> localData){
//The InsertHelper needs to have the db instance + the name of the table where you want to add the data
InsertHelper ih = new InsertHelper(this.db, TABLE_NAME);
Iterator<Entry<String, int[]>> it = localData.entrySet().iterator();
final int firstExampleColumn = ih.getColumnIndex("firstExampleColumn");
final int secondExampleColumn = ih.getColumnIndex("secondExampleColumn");
final int thirdExampleColumn = ih.getColumnIndex("thirdExampleColumn");
try{
this.db.setLockingEnabled(false);
while(it.hasNext()){
Entry<String, int[]> entry = it.next();
int[] values = entry.getValue();
ih.prepareForInsert();
ih.bind(firstExampleColumn, entry.getKey());
ih.bind(secondExampleColumn, values[0]);
ih.bind(thirdExampleColumn, values[1]);
ih.execute();
}
}catch(Exception e){e.printStackTrace();}
finally{
if(ih!=null)
ih.close();
this.db.setLockingEnabled(true);
}
}https://stackoverflow.com/questions/26574846
复制相似问题