首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在android中存储大量数据

在android中存储大量数据
EN

Stack Overflow用户
提问于 2014-10-26 15:52:00
回答 3查看 2.2K关注 0票数 1

我正在从restful服务器上提取大量json。我使用来自google的GSON库来遍历这个json,它工作得很好。现在,我想将所有json对象保存在sqlite中,但是我想使用一个事务同时添加所有这些对象。如果没有在一个数据结构中准备好所有的对象,这是很困难的。由于我一次遍历json一个对象,我想我必须将其存储在数据结构中,比如数组或散列图,然后使用数据库事务来快速执行插入。然而..。将大量数据(包括20万json对象)存储到内存中的结构中可以占用大量的内存,而且可能也会耗尽。什么是最好的方式,让所有的json对象进入我的sqlite,同时又不消耗大量的记忆,换句话说,存储和插入的方式,允许大量的回收。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-10-26 21:21:47

我知道这并不是在Android中处理大型json输入的最佳实现,但它确实工作得很好。

所以我的解决方案很简单:

在解析JSON代码时,使用准备语句和db事务来执行插入。因此,简而言之,一旦解析了JSON对象,获取该信息,使用准备语句和db事务将其插入到db中,然后转到下一个对象。

我刚刚通过JSON和GSON从远程服务器中提取了210 000行,每个字段有23个字段(即460万个值),同时将所有这些值插入到设备上的SQLite3 db中,时间不到5分钟,没有浪费任何内存。每一次解析/插入迭代都使用相同的内存量,并在下一次迭代中清理。

所以是的,有解决办法。显然,对于具有1000多条记录的商业应用程序或表来说,这不是最好的解决方案,但它对我的情况非常有用。

票数 0
EN

Stack Overflow用户

发布于 2014-10-26 17:03:24

如果您想在一个独特的时刻添加大量的数据,那么无论如何都需要大量的内存。20万个大型JSON对象占用一定的内存,您将而不是更改它。

您可以保持这种行为,但我认为这不是一个很好的解决方案,因为您在Android设备和服务器上都会产生巨大的内存消耗。如果您按部分接收数据并以这种方式添加它们,情况会更好:但是您需要控制服务器代码。

如果您是绝对,您必须保持这种行为,也许您应该同时接收所有数据,在一个巨大的JSON对象上解析它们,然后进行多个事务处理。检查每个事务是否被正确执行,如果没有,则将数据库恢复到一个良好的状态。这是个很糟糕的方法,IMHO.但我不知道你所有的限制。

完成:避免一次收到大量数据。最好提出多个请求,以获得部分数据集。它将使您的应用程序不再依赖于网络:如果您在网络上松开2秒,可能只有一个请求会失败。因此,您必须只重试一个请求,并再次收到一小部分数据。只有一个巨大的请求:如果你失去了网络,你将不得不重试整个请求.

票数 1
EN

Stack Overflow用户

发布于 2015-08-21 10:12:27

您是否曾经尝试过在Android数据库(SQLite)中添加大量数据(在我的例子中,我的意思是2600行数据)?

如果是这样的话,你很可能会走和我一样的路。

我尝试了一个正常的InsertStatement,这是慢的方式(10秒)。在我的模拟器里)。然后我尝试了PreparedStatements。时机更好,但仍然不能接受。(6秒)在写了几个小时令人沮丧的代码之后,我终于找到了一个很好的解决方案。

Android为InsertHelper提供了一种快速的批量插入方式。

要概述性能(在一台糟糕的计算机上使用仿真器测量,尝试插入2600行数据):

代码语言:javascript
复制
Insert-Statement
10 seconds
Prepared-Statements
6 seconds
InsertHelper
320 ms

您可以通过临时禁用线程锁来加快插入速度。这将获得大约30 %的性能。但是,重要的是要确保每次只有一个线程在插入数据时使用数据库,因为它不再是线程安全了。

代码语言:javascript
复制
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);
               }
       }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26574846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档