3

我在循环到 stringbuilder 的 asynctask 中出现内存不足错误。我的目标是使用它从服务器下载图像并存储在我的 sd 卡中。我的代码如下:

HttpClient httpclient = new DefaultHttpClient();
        httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);   
        HttpPost httppost = new HttpPost(severPath);        

        httppost.setEntity(params[0]);
        System.out.println("executing request " + httppost.getRequestLine());



            HttpResponse response = null;
            try {
                response = httpclient.execute(httppost);
            } catch (ClientProtocolException e6) {
                // TODO Auto-generated catch block
                e6.printStackTrace();
            } catch (IOException e6) {
                // TODO Auto-generated catch block
                e6.printStackTrace();
            }
            String output;
            System.out.println("Output from Server .... \n");

            BufferedReader br = null;
            try {
                br = new BufferedReader(
                        new InputStreamReader((response.getEntity().getContent())));
            } catch (IllegalStateException e5) {
                // TODO Auto-generated catch block
                e5.printStackTrace();
            } catch (IOException e5) {
                // TODO Auto-generated catch block
                e5.printStackTrace();
            }

             OutputStreamWriter outputStreamWriter = null;
            try {
                outputStreamWriter = new OutputStreamWriter(context.openFileOutput("LargeImages.txt", context.MODE_PRIVATE));
            } catch (FileNotFoundException e6) {
                // TODO Auto-generated catch block
                e6.printStackTrace();
            }
            int i = 0;


            StringBuilder builder = new StringBuilder();


            String Result = "";
                try {
                    for (String line = null; (line = br.readLine()) != null ; ) {
                                        builder.append(line.toString());

                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }




                    outputStreamWriter.close();

我正在摆脱内存分配错误。请帮忙。我尝试了很多方法,但也没有得到正确的方法。

4

3 回答 3

0

可能有两个问题。第一个 - 循环for (String line = null; (line = br.readLine()) != null ; )没有正确终止。尝试通过打开一个小文件(例如总共 10 行)来找出它。

第二个 - 它实际上是一个内存不足的情况。通过字符串获取图像可能不是最好的主意,因为图像可能非常重,并且创建大量字符串会导致自然内存错误。尝试寻找另一种方法。

于 2013-10-01T05:31:12.590 回答
0

如果您正在下载图像,那么您不应该使用Reader/Writer/StringBuilder它来存储它的内容。因为文件是二进制的,内容会因为类的character encoding使用而被打乱Reader/Writer

尝试使用InputStream/OutputStream并将内容直接存储到 sdcard 而不将其存储在内存中。

试试下面的代码:

InputStream in = response.getEntity().getContent();
OutputStream out = context.openFileOutput("LargeImages.txt", context.MODE_PRIVATE);
byte b[] = new byte[4096];
int i;
while ((i = in.read(b)) >= 0) {
    out.write(b, 0, i);
}
于 2013-10-01T05:31:46.767 回答
0

我没有看到实际写入输出流的代码。收盘前不应该有一条线,就像outputStreamWriter.print(builder)

关于你的问题。与其在 StringBuilder 中收集内存中的全部数据并一次写入,不如直接编写在 for 循环中获得的每一行。您根本不需要 StringBuilder。这是一个代码片段:

            try {
                for (String line = br.readLine(); line != null; line = br.readLine()) {
                    outputStreamWriter.append(line);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return;
            }

另外三点说明:

  • 当您收到异常时,您还应该停止操作,例如从您的方法返回。您上面的代码将打印 Stacktrace (这绝对有帮助),但随后会继续,这不会有太大帮助。只需return在每个printstackTrace.
  • 仍然有可能一行太长而无法记忆,但风险已降至最低。
  • 你下载的数据是二进制图像还是文本?您将其命名为图像,但您下载文本。请注意,字节和字符(用字符集编码)之间存在差异,并保持在您实际收到的范围内。
于 2013-10-01T05:33:23.320 回答