Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 强制纵向模式调整位图大小_Android_Out Of Memory_Virtual Machine_Portrait - Fatal编程技术网

Android 强制纵向模式调整位图大小

Android 强制纵向模式调整位图大小,android,out-of-memory,virtual-machine,portrait,Android,Out Of Memory,Virtual Machine,Portrait,每当我在onCreate中强制使用肖像模式时 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 我犯了一个错误 肖像模式与图像比例上的预算有什么关系 private void scaleFrom(BmpWrap image, Bitmap bmp) { if (image.bmp != null && image.bmp != bmp) { image.bmp

每当我在onCreate中强制使用肖像模式时

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
我犯了一个错误

肖像模式与图像比例上的预算有什么关系

private void scaleFrom(BmpWrap image, Bitmap bmp)
    {
      if (image.bmp != null && image.bmp != bmp) {
        image.bmp.recycle();
      }

      if (mDisplayScale > 0.99999 && mDisplayScale < 1.00001) {
        image.bmp = bmp;
        return;
      }
      int dstWidth = (int)(bmp.getWidth() * mDisplayScale);
      int dstHeight = (int)(bmp.getHeight() * mDisplayScale);
      image.bmp = Bitmap.createScaledBitmap(bmp, dstWidth, dstHeight, true);
    }

    private void resizeBitmaps()
    {

      scaleFrom(mBackground, mBackgroundOrig);
      for (int i = 0; i < mBOrig.length; i++) {
        scaleFrom(mB[i], mBOrig[i]);
      }
      for (int i = 0; i < mBlind.length; i++) {
        scaleFrom(mBlind[i], mBlindOrig[i]);
      }
      for (int i = 0; i < mFrozen.length; i++) {
        scaleFrom(mFrozen[i], mFrozenOrig[i]);
      }
      for (int i = 0; i < mTargeted.length; i++) {
        scaleFrom(mTargeted[i], mTargetedOrig[i]);
      }
      scaleFrom(mBlink, mBlinkOrig);
      scaleFrom(mWon, mWonOrig);
      scaleFrom(mLost, mLostOrig);

      mImagesReady = true;
    }

java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:498)
at android.graphics.Bitmap.createBitmap(Bitmap.java:465)
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:370)
at com.company.app.View$hread.scaleFrom(View.java:313)
at com.company.app.View$hread.resizeBitmaps(View.java:337)
at com.company.app.View$hread.setSurfaceSize(View.java:480)
at com.company.app.View.surfaceChanged(View.java:905)
at android.view.SurfaceView.updateWindow(SurfaceView.java:538)
at android.view.SurfaceView.dispatchDraw(SurfaceView.java:339)
at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
at android.view.View.draw(View.java:6745)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
at android.view.View.draw(View.java:6745)
at android.widget.FrameLayout.draw(FrameLayout.java:352)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1891)
at android.view.ViewRoot.draw(ViewRoot.java:1416)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1172)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1736)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:4701)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
private void scaleFrom(BmpWrap图像,位图bmp)
{
如果(image.bmp!=null&&image.bmp!=bmp){
image.bmp.recycle();
}
如果(mDisplayScale>0.99999&&mDisplayScale<1.00001){
image.bmp=bmp;
回来
}
int dstWidth=(int)(bmp.getWidth()*mDisplayScale);
int-dstwheight=(int)(bmp.getHeight()*mDisplayScale);
image.bmp=Bitmap.createScaledBitmap(bmp,dstWidth,dstHeight,true);
}
私有void resizeBitmaps()
{
scaleFrom(mBackground,mBackgroundOrig);
对于(int i=0;i
无论何时更改方向,应用程序都会完全重新加载,静态属性除外。(请看这里:)

这意味着您分配的所有位图(如果不是静态的)都将重新加载。 由于一个应用程序允许的内存为16MB(我听说有些设备上为24 MB),并且位图作为原始位图(读取而非压缩)存储在内存中,这会导致内存使用量激增,从而导致OOM

此外,位图使用的内存是在堆内存之外分配的,但被视为堆内存的一部分,因此即使使用ddms或MAT也无法实际跟踪该问题

请确保在onDestroy方法中回收所有位图,以便对其进行垃圾收集

最终让我摆脱困境的是这三行代码(hack):

不过要小心,它会影响性能(大约500到750毫秒),因此不适合FPS游戏,但对于应用程序来说,它是完全合理的

将它们放在createScaledBitmap调用的最开始处

它对我有用

编辑:

根据您对所讨论的位图所做的操作,您可以要求android向下采样打开它,占用更少的内存。我在处理这个问题时编写了这个函数。它尝试打开尽可能大的位图:

    private Bitmap getDownsampledBitmapFromFile(String fileName, int sampleSize) {

        //Try to free up some memory
        System.gc();
        System.runFinalization();
        System.gc();

        BitmapFactory.Options options=new BitmapFactory.Options();//reset object            
        byte[] tempBuffer=new byte[8000]; 
        options.inTempStorage = tempBuffer;
        options.inSampleSize=sampleSize;

        Bitmap downsampledBitmap = null;

        try {
            downsampledBitmap = BitmapFactory.decodeFile(fileNameToUpload, options);
        } catch (OutOfMemoryError e) {
            sampleSize ++;
        }

        return(downsampledBitmap);

    }

OOM异常是因为通过在方向更改时重新创建位图,本机堆已用完。有关背景信息,请参阅我在的帖子

解决这个问题的一种方法是(正如Yahel所说)在onDestroy中回收位图。尽管位图数据位于本机堆中,而且我们发现以下形式的代码(在onDestroy中)更有效地获取堆

mBitmap.recycle();
mBitmap = null;

gc();System.runFinalization();gc();image.bmp=Bitmap.createScaledBitmap(bmp,dstWidth,dstHeight,true);在我的帖子中添加了一个编辑,其中包含一个您可能想要尝试的函数。您在函数filenametopload中设置了什么变量?此错误也只发生在AVD emulator上,而不发生在内存较大的设备上。在我的个人欲望HD上,我从来没有遇到过问题,但在AVD上,我得到了这些错误。你知道为什么吗?我给你这个函数只是作为如何使用bitmapFactory和bitmapFactory.options创建位图的提示。在那之后,实现就是你的了
mBitmap.recycle();
mBitmap = null;