服务器以字节数组的形式向我的android应用程序发送图像。在循环中,每个接收到的字节数组被转换为要在ImageView中显示的位图。问题是,我的安卓设备(文斯)给OutOfMemoryError的时间后(如2-3分钟)。仿真器的情况也是如此。有什么办法可以避免这个错误吗?另外,我已经将largeHeap设置为true
日志:
2020-03-31 20:39:28.040 30083-30158/com.rollout.pcremoteclient E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: com.rollout.pcremoteclient, PID: 30083
java.lang.OutOfMemoryError: Failed to allocate a 153632 byte allocation with 105792 free bytes and 103KB until OOM, target footprint 536870912, growth limit 536870912
at java.lang.reflect.Array.newArray(Array.java:782)
at java.lang.reflect.Array.newInstance(Array.java:78)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1406)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
at com.rollout.pcremoteclient.MainActivity$1.run(MainActivity.java:30)MainActivity.java :
package com.rollout.pcremoteclient;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.util.logging.SocketHandler;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
Thread thread = new Thread(){
@Override
public void run(){
try {
Socket socket = new Socket("192.168.43.191",6777);
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
while (true) {
final byte[] image_bytearr = (byte[])objectInputStream.readObject();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
final Bitmap bmp = BitmapFactory.decodeByteArray(image_bytearr, 0, image_bytearr.length, options);
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bmp);
}
});
}
}catch (Exception e){
e.printStackTrace();
}
}
};
thread.start();
}
public void init(){
imageView = (ImageView) findViewById(R.id.imageView);
}
}ServerSide :
robot = new Robot();
rectangle = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
while (true) {
BufferedImage bufferedImage = robot.createScreenCapture(rectangle);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream);
byte[] image_byte_arr = byteArrayOutputStream.toByteArray();
objectOutputStream.writeObject(image_byte_arr);
}发布于 2020-03-31 18:05:01
最好的做法是减少服务器端的映像,因为android有一个内存内存限制,可以为每个应用程序提供内存,无论您的设备有9gb的ram (例如,操作系统根据设备屏幕分辨率给出的最大内存)。
但是为了减少本地内存的使用,您的内存使用量(但仍然可以得到一个OutOfMemoryError)是在解析后对本地图像进行压缩,并将这些图像转换为Webp格式,以进一步减小图像的最终大小,这些问题是图像处理的时间问题。
Conver to Webp (Google )和压缩
Bitmap bitmap;
String fileUrl;
//Get your file URL
//fileUrl
bitmap = BitmapFactory.decodeStream(fileUrl, null, null);
FileOutputStream out = this.openFileOutput(Utils.getFilenameFromUrl(Utils.getFilenameFromUrl(preview)), Context.MODE_PRIVATE);
bitmap.compress(Bitmap.CompressFormat.WEBP, 50, out);同样在您的AndroidManifest.xml中,打开大堆用法,将android:largeHeap="true"添加到<application>标记中
https://stackoverflow.com/questions/60954780
复制相似问题