内存不足异常

3
06-21 12:35:37.275: E/AndroidRuntime(12402): FATAL EXCEPTION: Thread-1864
 06-21 12:35:37.275: E/AndroidRuntime(12402): java.lang.OutOfMemoryError
 06-21 12:35:37.275: E/AndroidRuntime(12402):  at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)
 06-21 12:35:37.275: E/AndroidRuntime(12402):  at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:201)
 06-21 12:35:37.275: E/AndroidRuntime(12402):  at libcore.net.http.RetryableOutputStream.write(RetryableOutputStream.java:61)
 06-21 12:35:37.275: E/AndroidRuntime(12402):  at java.io.BufferedOutputStream.write(BufferedOutputStream.java:131)
 06-21 12:35:37.275: E/AndroidRuntime(12402):  at java.io.OutputStream.write(OutputStream.java:82)
 06-21 12:35:37.275: E/AndroidRuntime(12402):  at com.facebook.android.Util.openUrl(Util.java:190)
 06-21 12:35:37.275: E/AndroidRuntime(12402):  at com.facebook.android.Facebook.request(Facebook.java:563)
 06-21 12:35:37.275: E/AndroidRuntime(12402):  at dev.env.secvideo.SaveActivity$FBRequestListener.onComplete(SaveActivity.java:467)
 06-21 12:35:37.275: E/AndroidRuntime(12402):  at com.facebook.android.AsyncFacebookRunner$2.run(AsyncFacebookRunner.java:254)

当我尝试从我的应用程序将视频上传到Facebook时,我收到了以下错误消息。我的视频大小约为15-20 MB。我的代码在较低版本中运行正确。我只会在4.0以上的高版本中出现此错误。
我正在使用以下代码:
public byte[] readBytes(String path) throws IOException {

        InputStream is = new FileInputStream(path);
        ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(path.length());

        //int bufferSize = 30*1024;
        byte[] buffer = new byte[path.length()];

        int len = 0;
        while ((len = is.read(buffer)) != -1) {
            byteBuffer.write(buffer, 0, len);
        }
        return byteBuffer.toByteArray();
    }
    public class FBRequestListener implements RequestListener
    {

        @Override
        public void onComplete(String response, Object state) {

            byte[] data = null;
            String path = Environment.getExternalStorageDirectory()+"/recordvideooutput.3gp";
            String datapath = new File(path).getAbsolutePath();
            String datamsg = "My Video";
            Bundle params;
            try {
                //InputStream is = new FileInputStream(datapath);
                //data = readBytes(is);
                data = readBytes(datapath);
                params = new Bundle();
                params.putString(Facebook.TOKEN, access_token);
                params.putString("message", datamsg);
                params.putString("contentType", "video/quicktime");
                params.putByteArray("video.mov", data);
                String request = facebook.request("me/videos", params, "POST");
                Log.i("request", request);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onIOException(IOException e, Object state) {


        }

        @Override
        public void onFileNotFoundException(FileNotFoundException e,
                Object state) {


        }

        @Override
        public void onMalformedURLException(MalformedURLException e,
                Object state) {


        }

        @Override
        public void onFacebookError(FacebookError e, Object state) {


        }

    }

没有源代码,我们如何帮助您? - mithrop
你正在将整个文件加载到内存中。有没有办法从磁盘流式传输文件到网络? - brianestey
你所调用的 facebook.request 的对象是什么? - brianestey
我正在使用 Facebook.request 将我的视频分享到我的主页上。 - Dinesh Raj
但是它在哪里定义的,它是什么类型的对象?我们能看到相关代码吗? - brianestey
在全局声明中,使用Facebook SDK创建一个名为facebook的实例对象:Facebook facebook = new Facebook("AppKey"); - Dinesh Raj
3个回答

2
在你的Android清单文件中的应用程序标记下添加android:largeHeap="true"。这将增加可用内存空间。但是,这仅适用于API 11及以上版本。

1
谢谢Ashwin,现在它可以工作了,但上传需要更多时间,如何缩短上传时间? - Dinesh Raj
在发送视频之前,请先压缩它。 - tolgap

0

基本上,你不能按照你尝试的方式来做。因为你将整个文件读入内存,所以在它到达网络之前就已经耗尽了你可用的内存。

有一些选项可以帮助你解决这个问题:

  1. 你可以压缩视频,这意味着你的15MB可以被缩小。根据压缩的程度,你应该能够将此文件加载到内存中。然而,这并不是保证,你仍然可能遇到问题。

  2. 我已经检查了Facebook API,看起来他们不支持通过他们的Android SDK流式传输数据。这意味着你需要自己开发。他们确实有一个API可以在他们的网站上完成(http://developers.facebook.com/docs/reference/api/video/),所以你需要弄清楚如何使用该API,然后一旦你理解了它,就将你的数据流式传输到他们的Web服务,而不是尝试将所有数据加载到单个facebook.request对象中。

这里有一篇博客文章(http://developers.facebook.com/blog/post/493/),描述了如何将其作为POST请求执行。具体来说,引用博客中的内容:

要发布视频,请使用multipart/form-data将视频文件附件作为POST请求发送到https://graph-video.facebook.com/me/videos

有一个PHP示例,您可以从中提取关键部分并转换为Java。

如果我是你,我会尝试第二种方法。希望能帮到你。


只是提醒一下,largeHeap选项并不能解决问题。请查看文档(http://developer.android.com/guide/topics/manifest/application-element.html#largeHeap),特别是其中的`大多数应用程序不需要此选项,而应专注于减少其总体内存使用以改善性能。启用此选项也不能保证可用内存固定增加,因为某些设备受其总可用内存的限制。`如果您想要创建一个强大的应用程序,我建议您考虑流媒体技术。 - brianestey

0
有时候你需要增加Eclipse可用的工作内存,可以通过编辑Eclipse目录下的eclipse.ini文件来实现。最后一行的值默认为512m,这意味着只有512MB的内存可供Eclipse使用。将其增加即可为Eclipse提供更多的RAM。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接