Android Out of Memory错误:如何解决这个问题?

时间:2012-06-03 01:16:52

标签: android sqlite io out-of-memory stringwriter

我有一个应用程序,我正在尝试建立一个相当大的SQLite数据库(一个大约有5000行的表)。我已经构建了数据库类和所有内容,当我在较小规模(400行)上测试时,我的应用程序正常工作,但是现在当我想导入我的数据库时,我得到了内存不足的错误,我似乎无法找到一种绕行的方式。

数据库最初是在我的网络服务器上的MySQL上,由于某些奇怪的原因我无法转换它,但我设法生成一个带有查询的文本文件,添加所有5000行,大小为11.5mb。我在我的资源文件夹中有这个文件,我正在尝试将它放入我的数据库中:

public void onHandleIntent(Intent intent) {

        DBAdapter db = new DBAdapter(getApplicationContext());
        db.open();

        try {
            InputStream is = getAssets().open("verbs_sql.txt");
            db.executeSQL(convertStreamToString(is));
        } catch (IOException e) {}

        db.close();

        // Run main activity
        Intent i = new Intent(DatabaseReceiver.this, BaseActivity.class);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        DatabaseReceiver.this.startActivity(i);
    }

    public static String convertStreamToString(InputStream is) throws IOException {
        Writer writer = new StringWriter();

        char[] buffer = new char[2048];
        try {
            Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            int n;
            while ((n = reader.read(buffer)) != -1) {
                writer.write(buffer, 0, n);
            }
        } finally {
            is.close();
        }
        String text = writer.toString();
        return text;
    }
}

StringWriter()上发生内存不足错误,所以它看起来喜欢把那个大文件放到内存中。我怎么解决这个问题?我也试过循环遍历所有5000行但是在30秒之后我再次失去内存。

4 个答案:

答案 0 :(得分:1)

在Google的视频中:

http://www.youtube.com/watch?v=_CruQY55HOk

描述了内存管理。由于您的方法适用于小规模,听起来您使用的内存比应用程序的可用堆更多。

该视频介绍了内存管理以及如何增加堆大小(相信它来自Android 4.0及更高版本)。

答案 1 :(得分:1)

我遇到了同样的问题。我尝试了很多方法来解决它但失败了。最后我找到了原因,我想知道。在我的情况下,错误的原因是我在日志cat中打印整个响应字符串。这些数据非常庞大,需要堆内存。 请注意以下

  1. 删除批量数据的日志cat打印。
  2. 尝试在一个共振下仅使用一个J-SON阵列进行所有操作(对所有人重复使用)。
  3. 尽量避免使用数组列表。
  4. 当每个项目从J-Son阵列迭代时插入项目。这意味着不要遵循我们将项目作为对象的方法,并将其放入数组列表并将数组列表传递给DB-helper,然后从那里迭代对象并插入。

答案 2 :(得分:0)

Sqlite数据库只是文件,当你试图在手机上运行数千个插件时,你会一遍又一遍地使用SD卡进行文件访问。

您要做的是在桌面上创建sqlite数据库,并在应用程序中包含已创建的数据库。如果您需要定期更新数据库中的信息,您可以将其发布到网站上并让应用程序下载,只需确保只通过Wifi进行大量下载。

有关详细信息,请查看此Tech Talk

编辑:有关在Windows中创建sqlite数据库并将其包含在应用程序中的详细信息,请参阅this

答案 3 :(得分:0)

我相信你可以按照你想要的方式做到这一点。您发布的代码的问题是您尝试将整个文件转换为字符串。我相当肯定即使在桌面计算机上也会失败。

如果您尝试一次读取一行并执行SQL,我相信您会有更好的运气。然后阅读下一行。您还可以通过传递zip来减小文件的大小。

如果我能找到几分钟,我会附上一些代码。