【问题标题】:Avoiding OutOfMemory exception when making large network requests from Android application从 Android 应用程序发出大型网络请求时避免 OutOfMemory 异常
【发布时间】:2012-02-29 09:03:51
【问题描述】:

我正在开发一个应用程序,在首次启动时,我预计会下载大量 JSON 格式的数据(比如 10-20 MB)。所有这些数据都在单个网络请求中传输(因为数据是根据请求动态生成的)。以下代码在接收数据时抛出OOM异常(in builder.append()):

  public static String readToString(InputStream stream) throws IOException {
    BufferedReader in = null;
    StringBuilder builder = new StringBuilder();
    in = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
    char[] buffer = new char[1024];
    int read = 0;
    while ((read = in.read(buffer, 0, 1024)) > 0) {
      builder.append(buffer, 0, read);
    }
    in.close();
    return builder.toString();
  }

我可以做些什么来避免这个错误?我正在考虑尝试将数据保存到临时文件中,然后对其进行处理。但我不确定它是否会起作用。 另一种可能性似乎是将网络 IO 分为两部分:第一部分,应用程序接收有关它应该下载的数据,第二部分它实际下载数据。

有什么建议吗?

【问题讨论】:

  • 您可以将数据保存到临时文件中。关于方式#2,如果数据也很大,它可能是相同的。所以好的方法是临时文件。
  • 将数据保存到本地文件并进行处理,我认为这是个好主意。

标签: android out-of-memory


【解决方案1】:

按照您的第一个想法 - 将数据保存到一个临时文件(请使用 sd 卡。20mb 的内部存储空间太大了)。您首先需要打开连接以供下载。

InputStream is = URL("your_request_string").openStream();

然后在sdcard中新建一个文件

File f = new File(Environment.getExternalStorageDirectory(), "temp.dat");

使用您新创建的文件,打开一个 OutputStream。

FileOutputStream = new FileOutputStream(f);

您现在可以使用这段代码进行传输:

public static void CopyStream(InputStream is, OutputStream os) {
    final int buffer_size=8192;
    try
    {
        byte[] bytes=new byte[buffer_size];
        for(;;)
        {
          int count=is.read(bytes, 0, buffer_size);
          if(count==-1)
              break;
          os.write(bytes, 0, count);
        }
    }
    catch(Exception ex){}
}

【讨论】:

  • 这一切都很好,但没有解决实际问题,即解析 20Mb JSON 文件。
  • 我想你已经在使用某种处理大量数据的 json 解析器了。如果没有,试试 Jackson - jackson.codehaus.org
  • 是的,下载数据并将其作为文件存储在SDCard中没有问题。但是当我从 SDCard 读取文件并存储为自定义类的数组列表时,它会抛出内存不足异常。有什么解决办法吗?
【解决方案2】:

从 API 11 开始,http://developer.android.com/reference/android/util/JsonReader.html 用于读取 Json 数据流而不分配整个大字符串。

对于以前的版本,有大量第三方 JSON 库提供基于事件的流读取功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多