Android 如何在没有内存异常的情况下根据屏幕大小缩放位图

Android 如何在没有内存异常的情况下根据屏幕大小缩放位图,android,bitmap,out-of-memory,Android,Bitmap,Out Of Memory,在我的活动中,我正在创建一个宽度和高度与设备分辨率(宽度和高度)相同的位图 我在做什么 位图mBitmap=Bitmap.createBitmap(屏幕宽度、屏幕高度、, 位图.Config.ARGB_8888) 屏幕宽度和屏幕高度为 screenHeight = displaymetrics.heightPixels; screenWidth = displaymetrics.widthPixels; 现在,如果我制作这个位图,我的堆会增加到19mb,这不是很好 告诉我两件事

在我的活动中,我正在创建一个宽度和高度与设备分辨率(宽度和高度)相同的位图

我在做什么

位图mBitmap=Bitmap.createBitmap(屏幕宽度、屏幕高度、, 位图.Config.ARGB_8888)

屏幕宽度和屏幕高度为

    screenHeight = displaymetrics.heightPixels;
    screenWidth = displaymetrics.widthPixels;
现在,如果我制作这个位图,我的堆会增加到19mb,这不是很好

告诉我两件事

1。根据屏幕大小和高度以及占用的最小内存创建位图的好方法是什么

2。使用位图后如何销毁它?

请给我一个小的源代码或源代码链接

  • 对于屏幕大小和高度以及占用的内存最少的情况,创建位图的好方法是什么

  • 永远不要用
    屏幕高度或宽度创建
    位图,因为根据设备的
    密度
    ,这将是非常巨大的。而是使用屏幕的
    高度
    宽度
    ,并计算
    纵横比。现在将
    高度
    固定为一个常量(如1200px),然后根据
    纵横比计算
    宽度
    ImageView
    或任何其他视图将正确缩放此视图
  • 如果确实需要透明度,请使用
    Bitmap.Config.ARGB_8888
    ,如果不需要,可以使用
    RGB_565
    或此处列表中的其他内容:
  • 如果不是创建新的
    位图
    ,而是从某些资源解码
    位图
    ,请遵循以下几点:
  • 您需要使用
    BitmapFactory.Options.inSampleSize
    来减少
    采样。那么,如果您已经知道高度和宽度,那么如何计算采样中的
    inSampleSize
    ?请参阅此处:
  • 所以你做了所有这些,但是采样中的
    inSampleSize
    仍然不够高,你得到了
    OutOfMemoryError
    ?不要担心,如果是这种情况,您需要
    捕获
    OutOfMemoryError
    ,并在这一过程中增加
    采样
    ,然后再次执行位图解码。把这个逻辑放在一个循环中,这样崩溃就不会发生。

  • 使用位图后如何销毁它

  • 这真的很简单。确保调用
    Bitmap.recycle()
    方法。并删除对位图的所有引用。一旦您这样做,资源将被释放,GC将进行清理
  • 更新:当你用
    屏幕宽度和
    屏幕高度创建位图时,你会得到一个巨大的位图。而是创建一个适合整个屏幕的分辨率较低的位图。您可以看到下面关于如何实现这一点的代码

        float screenHeight = displaymetrics.heightPixels;
        float screenWidth = displaymetrics.widthPixels;
    
        float aspectRatio  = screenWidth/screenHeight;
    
        int modifiedScreenHeight = 1000;
        int modifiedScreenWidth = (int) (modifiedScreenHeight * aspectRatio);
    
        Bitmap mBitmap = Bitmap.createBitmap(modifiedScreenWidth, modifiedScreenHeight, Bitmap.Config.ARGB_8888);
    

    现在您得到了具有正确纵横比的位图。您可以使用
    ImageView
    中的位图填充整个屏幕。确保您将
    android:scaleType=“fitXY”
    放入
    ImageView

    您可能希望通过阅读开发者网站查看此视频@iGoDa我完全理解这一点,但我希望根据需要提供解决方案,我希望获得屏幕大小的位图,即当它应该处于其最小大小时,您可以通过调用destroyDrawingCache()方法来销毁位图。例如:iv.destroyDrawingCache()或frame.destroyDrawingCache()这里的iv和frame分别是ImageView和FrameLayout。你能解释一下你所说的永远不要创建屏幕高度或宽度的位图,而是使用屏幕的高度和宽度并计算纵横比是什么意思吗?我想制作一个扩展到整个屏幕宽度和高度的位图?你有什么建议,请用代码解释,很好,但有一点我还不清楚。。您正在使int modifiedScreenHeight=1000;我们怎么知道这对所有设备来说都是正确的高度?这1000不是屏幕的高度,而是图像的分辨率。您需要根据您提供的内存选择此值。我相信1200px宽或高的图像在所有手机上都很好看。通过这样做,我得到了以下错误:java.lang.IllegalArgumentException:宽度和高度必须大于0