【问题标题】:Out of Memory Exception CreateBitmap内存不足异常 CreateBitmap
【发布时间】:2015-11-26 03:14:44
【问题描述】:

我目前正在开发我的第一个 android 应用程序,该应用程序涉及用户能够在其库存中获取武器。武器从drawables随机拼凑在一起(刀柄+刀片+握把..等)。库存是一个带有自定义 ArrayAdapter 的网格视图,用于显示武器图标。

问题是一旦生成了大约 15 个武器,我就会收到 OutOfMemoryException。我的目标是让 Inventory 能够支持数百个项目。从日志中,我能够看到问题出在此处: Bitmap result = Bitmap.createBitmap(woh300, woh300, Bitmap.Config.ARGB_8888);我把位图做的这么大是因为我让用户能够点击物品栏中的武器图标,这会带来它们的放大图像。

这是它的日志:

 java.lang.OutOfMemoryError: Failed to allocate a 1930512 byte allocation with 434524 free bytes and 424KB until OOM
            at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
            at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
            at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:726)
            at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:547)
            at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:575)
            at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:605)
            at com.example.android.justdoit.Weapon.<init>(Weapon.java:31)
            at com.example.android.justdoit.UpdateInvTask.onPostExecute(UpdateInvTask.java:48)
            at com.example.android.justdoit.UpdateInvTask.onPostExecute(UpdateInvTask.java:17)
            at android.os.AsyncTask.finish(AsyncTask.java:632)
            at android.os.AsyncTask.access$600(AsyncTask.java:177)
            at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:145)
            at android.app.ActivityThread.main(ActivityThread.java:5942)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)

我的武器类:

public class Weapon extends Equipment{
    public Weapon(Context context){
        //get the array of drawables located in the res/values/weapons.xml
        Resources res = context.getResources();
        TypedArray handles = res.obtainTypedArray(R.array.handles);
        TypedArray hilts = res.obtainTypedArray(R.array.hilts);
        TypedArray blades = res.obtainTypedArray(R.array.blades);
        TypedArray middles = res.obtainTypedArray(R.array.middles);
        TypedArray ends = res.obtainTypedArray(R.array.ends);
        //randomize the grip, hilt, blade
        Random rand = new Random();
        Bitmap handle = BitmapFactory.decodeResource(context.getResources(), handles.getResourceId(rand.nextInt(handles.length()), 0));
        Bitmap hilt = BitmapFactory.decodeResource(context.getResources(), hilts.getResourceId(rand.nextInt(hilts.length()), 0));
        Bitmap blade = BitmapFactory.decodeResource(context.getResources(), blades.getResourceId(rand.nextInt(blades.length()), 0));
        Bitmap end = BitmapFactory.decodeResource(context.getResources(), ends.getResourceId(rand.nextInt(ends.length()), 0));
        Bitmap middle = BitmapFactory.decodeResource(context.getResources(), middles.getResourceId(rand.nextInt(middles.length()), 0));

        Bitmap[] parts = new Bitmap[5];
        parts[0] = handle;
        parts[1] = hilt;
        parts[2] = blade;
        parts[3] = middle;
        parts[4] = end;

        int woh5 = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, res.getDisplayMetrics()));
        int woh25 = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 25, res.getDisplayMetrics()));
        int woh130 = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 130, res.getDisplayMetrics()));
        int woh138= Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 138, res.getDisplayMetrics()));
        int woh162 = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 162, res.getDisplayMetrics()));
        int woh170 = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 170, res.getDisplayMetrics()));
        int woh172 = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 172, res.getDisplayMetrics()));
        int woh258 = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 258, res.getDisplayMetrics()));
        int woh300 = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 300, res.getDisplayMetrics()));

        Bitmap result = Bitmap.createBitmap(woh300, woh300, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();

        //rect is left, top, right, bottom
        //set the full image.  icon is a scaled-down version of the full image
        canvas.drawBitmap(parts[2], null, new Rect(woh5 * 25, woh5 * 6, woh5 * 35, woh5 * 37), paint);
        canvas.drawBitmap(parts[0], null, new Rect(woh138, woh5 * 37, woh162, woh5 * 52), paint);
        canvas.drawBitmap(parts[1], null, new Rect(woh25*3, woh172, woh25*9, woh5 * 42), paint);
        canvas.drawBitmap(parts[3], null, new Rect(woh130, woh172, woh170, woh5 * 42), paint);
        canvas.drawBitmap(parts[4], null, new Rect(woh138, woh258, woh162, woh5 * 57), paint);
        setFullImage(result);

        //recycle the typedarrays
        result = null;
        canvas = null;
        handles.recycle();
        hilts.recycle();
        blades.recycle();
        middles.recycle();
        ends.recycle();
    }
}

我一直在阅读 Android 开发人员指南的“管理位图内存”部分,但作为我的第一个应用程序,我知道我的位图创建可能还很遥远,我想如果我需要完全更改在尝试更好地管理内存之前生成位图的方式。谢谢。

【问题讨论】:

  • 尝试调整位图大小

标签: android memory bitmap


【解决方案1】:

请看here

图片有各种形状和大小。在许多情况下,它们更大 比典型的应用程序用户界面 (UI) 所需的更多。为了 例如,系统图库应用程序显示使用拍摄的照片 您的 Android 设备的摄像头通常要高得多 分辨率高于设备的屏幕密度。

鉴于您的内存有限,理想情况下您只需要 在内存中加载较低分辨率的版本。较低的分辨率 版本应该与显示它的 UI 组件的大小相匹配。一个 分辨率更高的图像不会提供任何可见的好处, 但仍会占用宝贵的内存并产生额外的性能 由于额外的动态缩放而产生的开销。

【讨论】:

  • 感谢您的回复。构成武器的每个组件都是一个大约 100-400 像素 x 100-400 像素的 png。所以我想这使得组合的部分非常大。但理想情况下,我希望能够在库存中拥有数百种武器,因此调整可绘制对象的大小似乎还不够?
  • @user2562568 您可以使用GridView 来展示您的武器。 GridView 实现了延迟加载。
猜你喜欢
  • 2011-05-05
  • 2010-10-05
  • 1970-01-01
相关资源
最近更新 更多