如何为 Android 套接字上接收到的文件分配 20 MB

How to allocate 20 MB for file received on socket in Android

我不断收到 "out of memory" 问题。我看到很多线程,我明白 Android OS 限制主要内存块。但是这些文件共享应用程序是如何工作的呢?

我的代码在 10 MB 以下时工作正常,但在 10-15 MB 时有时有效,有时无效,而在 15 MB 以上时它从不工作。

我在这里尝试分配大约 11 MB,但有时也会失败。

我在 Manifest 中尝试了 android:largeHeap="true" 。没有帮助。

实际上,我必须移动一些已经压缩的视频。有什么建议吗?

我的代码片段:

 public class FileTxThread extends Thread {
        private  ServerSocket serverSocket;
        private  Socket clientSocket;
        private InputStream inputStream;
        private FileOutputStream fileOutputStream;
        private BufferedOutputStream bufferedOutputStream;
        private  int filesize = 11728640; // filesize temporary hardcoded
        private  int bytesRead;
        private  int current = 0;
        Socket socket;

        FileTxThread(Socket socket){
            this.socket= socket;
            Log.d("naval", "constructor file thread initialized");
        }

        @Override
        public void run() {

            Log.d("lvmh", "Run function  file thread");
            byte[] mybytearray = new byte[filesize];    //create byte array to buffer the file
            try {
                inputStream = socket.getInputStream();


                // check for SD card mounted
                if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
                {
                    Log.d("naval", "Mounted");
                }

                bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                Log.d("lvmh","Rceiving setting path"+imageCount);



                //System.out.println("Receiving...");


                //following lines read the input slide file byte by byte
                bytesRead = inputStream.read(mybytearray, 0, mybytearray.length);
                current = bytesRead;

                do {
                    bytesRead = inputStream.read(mybytearray, current, (mybytearray.length - current));
                    if (bytesRead >= 0) {
                        current += bytesRead;
                    }
                } while (bytesRead > -1);
                Log.d("lvmh", ">>>>>Receiving" + bytesRead);
                Log.d("lvmh",">>>>>navalllllllllll bytes read - "+current);
                bytesRead = 0; //reset


                try {
                    if(current>20)
                    {
                        fileOutputStream = new FileOutputStream(Environment.getExternalStorageDirectory() + "/lvmh/"+imageCount+"img.mp4");
                        videoflag = true;
                        Log.d("lvmh","Mp4 received in bytes- "+current);
                    }
                    else{
                        fileOutputStream = new FileOutputStream(Environment.getExternalStorageDirectory() + "/lvmh/" +imageCount+"img.jpg");
                        Log.d("lvmh","Image received in bytes- "+current);
                    }

                }catch (IOException e)
                {
                    e.printStackTrace();
                }

                bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                Log.d("LVMH","Rceiving setting path"+imageCount);


                bufferedOutputStream.write(mybytearray, 0, current);

socket.setReceiveBufferSize(11728640); //11.72864 MB -- 这就是为什么有时您会在 10-15 MB

上失败

因为,你不需要知道这里的impl,你只需要调用socket.setReceiveBufferSize(11728640);,它就会解决你的问题。 impl 是 LocalSocketImpl class (link) 的实例。但是,如果您想了解更多,setReceiveBufferSize() 的实现如下:.

public void setReceiveBufferSize(int size) throws IOException 
    {
        impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
    }

了解更多:https://alvinalexander.com/java/jwarehouse/android/core/java/android/net/LocalSocket.java.shtml

当您调用 setReceiveBufferSize() 时,当使用 setsockopt(2) 设置时,内核将这个值加倍(以允许 space 用于簿记开销),并且这个加倍的值由 getsockopt( 2).参见 link:http://man7.org/linux/man-pages/man7/socket.7.html

现在,您的套接字有双倍大小的缓冲区 11728640 KB。您不应该遇到“内存不足”问题。

请注意 heap spacesocket 无关。 SocketBuffer 有关。

默认大小为 4K。您可以在此处找到此信息。 https://developer.android.com/reference/java/net/SocketOptions.html#SO_RCVBUF

SO_RCVBUF 常数是提示 OS 相应地改变 ReceiveBuffer 的大小。