首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在安卓系统中处理OutOfMemoryError

如何在安卓系统中处理OutOfMemoryError
EN

Stack Overflow用户
提问于 2020-03-31 15:58:07
回答 1查看 268关注 0票数 0

服务器以字节数组的形式向我的android应用程序发送图像。在循环中,每个接收到的字节数组被转换为要在ImageView中显示的位图。问题是,我的安卓设备(文斯)给OutOfMemoryError的时间后(如2-3分钟)。仿真器的情况也是如此。有什么办法可以避免这个错误吗?另外,我已经将largeHeap设置为true

日志:

代码语言:javascript
复制
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 :

代码语言:javascript
复制
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 :

代码语言:javascript
复制
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);
    }
EN

回答 1

Stack Overflow用户

发布于 2020-03-31 18:05:01

最好的做法是减少服务器端的映像,因为android有一个内存内存限制,可以为每个应用程序提供内存,无论您的设备有9gb的ram (例如,操作系统根据设备屏幕分辨率给出的最大内存)。

但是为了减少本地内存的使用,您的内存使用量(但仍然可以得到一个OutOfMemoryError)是在解析后对本地图像进行压缩,并将这些图像转换为Webp格式,以进一步减小图像的最终大小,这些问题是图像处理的时间问题。

Conver to Webp (Google )和压缩

代码语言:javascript
复制
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>标记中

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60954780

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档