java - 屏幕旋转后创建位图时出现 OutOfMemoryError

标签 java android out-of-memory

我正在使用 PhotoView 在我的应用程序中显示图像,但是当我旋转设备 3 或 4 次时出现 OutOfMemory 错误,这是什么问题?如何正确清理 PhotoView

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        // Get intent, action and MIME type
        Intent intent = getIntent();
        String action = intent.getAction();
        String type = intent.getType();

        if (Intent.ACTION_SEND.equals(action) && type != null) {
            if ("text/plain".equals(type)) {
                handleSendText(intent); // Handle text being sent
            } else if (type.startsWith("image/")) {
                handleSendImage(intent); // Handle single image being sent
            }
        } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
            if (type.startsWith("image/")) {
                handleSendMultipleImages(intent); // Handle multiple images being sent
            }
        } else {
            // Handle other intents, such as being started from the home screen
        }


    }



    void handleSendText(Intent intent) {
        String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
        if (sharedText != null) {
            Toast.makeText(this, sharedText, Toast.LENGTH_LONG).show();
        }
    }

    void handleSendImage(Intent intent) {
        Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
        if (imageUri != null) {
            Toast.makeText(this, imageUri.toString(), Toast.LENGTH_LONG).show();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);//OOM here
                PhotoView photoView = (PhotoView) findViewById(R.id.img);
                photoView.setImageBitmap(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    void handleSendMultipleImages(Intent intent) {
        ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
        if (imageUris != null) {
        }



    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        ((PhotoView)findViewById(R.id.img)).setImageBitmap(null);
        ((PhotoView)findViewById(R.id.img)).setImageDrawable(null);
        ((PhotoView)findViewById(R.id.img)).setImageResource(0);
    }
}

最佳答案

有时,仅将 ImageView 的位图或可绘制对象设置为 null 是不够的。您将需要明确回收位图。

为此,将您的变量 bitmap 转换为一个字段(全局变量)并在销毁时回收它。

public class MainActivity extends AppCompatActivity {

    private Bitmap bitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...    

加载位图时,加载如下:

if(bitmap != null) bitmap.recycle();
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);

最后在 onDestroy 中,将位图回收为:

@Override
protected void onDestroy() {
    ((PhotoView)findViewById(R.id.img)).setImageBitmap(null);
    if(bitmap != null) bitmap.recycle();
    super.onDestroy();
}

关于java - 屏幕旋转后创建位图时出现 OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52343560/

相关文章:

linux - 为什么 PostgreSQL 在执行长时间运行的 INSERT … SELECT … 时不保存到磁盘?

java - 能否绕过 HEAP 从 HTTP 直接将字节流写入 SDCard?

java - 为什么需要通过 getErrorStream() 来运行进程?

java - 使用 TCP 与 Spring 集成生成 MessageSource

java - iText7可以用IVS(表意变化序列)显示字体吗?

android - 为什么找不到adb?

java - JPA 查询与获取/连接仅检索某些关联

android - 定期将数据从服务发送到绑定(bind) Activity

android - 我无法通过 GCM 从服务器接收推送通知?

MySQL存储过程优化