有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java微小的图像,并没有旋转,但仍然会脱离内存错误:位图大小超过VM预算

我花了一上午的时间阅读了一页又一页关于这个错误的StackOverflow帖子,但他们问题的根本原因似乎总是1)他们有非常大的图像需要向下采样,或者2)他们在一次或多次设备旋转后受到影响,导致活动被破坏并多次重新创建

我得到了这个错误(只有很少),但我的应用程序只允许纵向,所以没有旋转是可能的,我所有的图像都非常小。我确实有很多图像,但它们都很小。这是一个计算器应用程序,所以每个按钮都有图像。mdpi的图像只有1.9k,hdpi的图像只有2.8k。这些都是很小很小的图像。我通过Photoshop对它们进行了处理,将所有样本缩减为8比特PNG。下面是我的一个图像的示例:http://geekqi.com/StackOverflow/OutOfMemoryImage.png

大约有80个这样的图像按钮(一次只有40个在屏幕上)。我有两个视图,每个视图有40个ImageButtons,当您按下按钮时,其中一个视图隐藏,另一个视图显示(提供Shift功能以允许访问更多功能)。每个按钮都有一个标准图像和一个高亮显示的图像。所以,总的来说,我处理的是160个微小的图像。最大的一个是2.8k,所以其中160个是448k。。。即使ImageButton的开销是这个大小的两倍,也不到1MB

下面是我收到的stacktrace。它引用了第296行,看起来像:

<ImageButton 安卓:id="@+id/buttonRND" 安卓:src="@drawable/image_rnd" 安卓:hapticFeedbackEnabled="true" style="@style/CalculatorButton"/>

下面是我正在处理的堆栈跟踪:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mydomain.myapp/com.mydomain.myapp.CalculatorTabActivity}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mydomain.myapp/com.mydomain.myapp.MyCalculator}: 安卓.view.InflateException: Binary XML file line #296: Error inflating class <unknown>
       at 安卓.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
       at 安卓.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
       at 安卓.app.ActivityThread.access$2300(ActivityThread.java:125)
       at 安卓.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
       at 安卓.os.Handler.dispatchMessage(Handler.java:99)
       at 安卓.os.Looper.loop(Looper.java:123)
       at 安卓.app.ActivityThread.main(ActivityThread.java:4627)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:521)
       at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
       at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:629)
       at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mydomain.myapp/com.mydomain.myapp.MyCalculator}: 安卓.view.InflateException: Binary XML file line #296: Error inflating class <unknown>
       at 安卓.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
       at 安卓.app.ActivityThread.startActivityNow(ActivityThread.java:2503)
       at 安卓.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
       at 安卓.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
       at 安卓.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:651)
       at 安卓.widget.TabHost.setCurrentTab(TabHost.java:323)
       at 安卓.widget.TabHost.addTab(TabHost.java:213)
       at com.mydomain.myapp.CalculatorTabActivity.setupTab(CalculatorTabActivity.java:191)
       at com.mydomain.myapp.CalculatorTabActivity.onCreate(CalculatorTabActivity.java:95)
       at 安卓.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
       at 安卓.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
       ... 11 more
Caused by: 安卓.view.InflateException: Binary XML file line #296: Error inflating class <unknown>
       at 安卓.view.LayoutInflater.createView(LayoutInflater.java:513)
       at com.安卓.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
       at 安卓.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)
       at 安卓.view.LayoutInflater.rInflate(LayoutInflater.java:618)
       at 安卓.view.LayoutInflater.rInflate(LayoutInflater.java:621)
       at 安卓.view.LayoutInflater.rInflate(LayoutInflater.java:621)
       at 安卓.view.LayoutInflater.rInflate(LayoutInflater.java:621)
       at 安卓.view.LayoutInflater.inflate(LayoutInflater.java:407)
       at 安卓.view.LayoutInflater.inflate(LayoutInflater.java:320)
       at 安卓.view.LayoutInflater.inflate(LayoutInflater.java:276)
       at com.安卓.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:210)
       at 安卓.app.Activity.setContentView(Activity.java:1647)
       at com.mydomain.myapp.MyCalculator.configureActivity(MyCalculator.java:1042)
       at com.mydomain.myapp.MyCalculator.onCreate(MyCalculator.java:1111)
       at 安卓.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
       at 安卓.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
       ... 21 more
Caused by: java.lang.reflect.InvocationTargetException
       at 安卓.widget.ImageButton.<init>(ImageButton.java:78)
       at java.lang.reflect.Constructor.constructNative(Native Method)
       at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
       at 安卓.view.LayoutInflater.createView(LayoutInflater.java:500)
       ... 36 more
Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
       at 安卓.graphics.Bitmap.nativeCreate(Native Method)
       at 安卓.graphics.Bitmap.createBitmap(Bitmap.java:468)
       at 安卓.graphics.Bitmap.createBitmap(Bitmap.java:435)
       at 安卓.graphics.Bitmap.createScaledBitmap(Bitmap.java:340)
       at 安卓.graphics.BitmapFactory.finishDecode(BitmapFactory.java:590)
       at 安卓.graphics.BitmapFactory.decodeStream(BitmapFactory.java:564)
       at 安卓.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:425)
       at 安卓.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
       at 安卓.content.res.Resources.loadDrawable(Resources.java:1709)
       at 安卓.content.res.Resources.getDrawable(Resources.java:581)
       at 安卓.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:162)
       at 安卓.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:787)
       at 安卓.graphics.drawable.Drawable.createFromXml(Drawable.java:728)
       at 安卓.content.res.Resources.loadDrawable(Resources.java:1694)
       at 安卓.content.res.TypedArray.getDrawable(TypedArray.java:601)
       at 安卓.widget.ImageView.<init>(ImageView.java:118)
       at 安卓.widget.ImageButton.<init>(ImageButton.java:82)
       ... 40 more

我已经阅读了所有关于追踪Android内存“泄漏”的链接,但它们也涉及到旋转,我的应用程序不允许旋转

我可以做些什么来发现并解决此问题


共 (2) 个答案

  1. # 1 楼答案

    这看起来像是我几个月前遇到的一个可怕的问题

    应用程序中是否有透明PNG图像/背景层(不限于崩溃发生时的活动)

    我试图做的是通过单独保存图像层并将它们放在应用程序中来最小化文件大小(因为我会在其他地方单独使用一些层)

    这产生了一个与您描述的类似的堆栈跟踪

    希望这有帮助

  2. # 2 楼答案

    你不需要旋转应用程序来重启活动。开始另一项活动,然后开始原来的活动就足够了

    你是否在活动中保留对图像的引用?你怎么保存它们?在田野里?你指的是图像绘制工具吗