【问题标题】:Repeating 6 bitmas taken from drawable on map causes out of memory error重复从可绘制地图中获取的 6 个位图会导致内存不足错误
【发布时间】:2013-01-22 19:24:22
【问题描述】:

我已经尝试在这个网站和其他一些网站上找到解决我的问题的方法,但没有运气。我在我的应用程序上设置了地图(谷歌地图 V2)。这张地图充满了标记(大约 450 个),每个标记都有一个来自可绘制文件的图标集。可绘制文件总共有 6 个,因此大约有 450 个标记重复 6 个可绘制文件(每个不同的图标指的是地图上的一个位置)。当我第一次启动地图时,没有任何问题,一切正常。但是,如果我返回上一个屏幕并再次启动地图,应用程序会因内存不足错误而崩溃。我认为问题是由于系统将所有位图都保存在内存中,资源浪费令人难以置信,因为可绘制对象只有六个。

我尝试按照here 的建议将位图引用到应用程序上下文,但没有好的结果。有没有简单的方法来解决这个问题?

第 324 行:

if (IDTipologia.get(i).equals("1")) {
            setLoghino(R.drawable.chieseluoghidiculto);
            //iconcina = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE);
            Bitmap icon = BitmapFactory.decodeResource(getApplicationContext().getResources(),
                    R.drawable.markerchiese);
            iconcina = BitmapDescriptorFactory.fromBitmap(icon);
}

以此类推,直到第 6 个可绘制对象。

Logcat:

E/AndroidRuntime(10990): FATAL EXCEPTION: main
E/AndroidRuntime(10990): java.lang.OutOfMemoryError
E/AndroidRuntime(10990):    at android.graphics.Bitmap.nativeCreateFromParcel(Native   Method)
E/AndroidRuntime(10990):    at android.graphics.Bitmap.access$000(Bitmap.java:28)
E/AndroidRuntime(10990):    at android.graphics.Bitmap$1.createFromParcel(Bitmap.java:1052)
E/AndroidRuntime(10990):    at android.graphics.Bitmap$1.createFromParcel(Bitmap.java:1044)
E/AndroidRuntime(10990):    at com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate$Stub.onTransact(IBitmapDescriptorFactoryDelegate.java:101)
E/AndroidRuntime(10990):    at android.os.Binder.transact(Binder.java:297)
E/AndroidRuntime(10990):    at com.google.android.gms.internal.h$a$a.a(Unknown Source)
E/AndroidRuntime(10990):    at com.google.android.gms.maps.model.BitmapDescriptorFactory.fromBitmap(Unknown Source)
E/AndroidRuntime(10990):    at it.eventitrapani.appaeventitp.ElencoMappaTutteCoseDaVedere.addMarkersToMap(ElencoMappaTutteCoseDaVedere.java:324)
E/AndroidRuntime(10990):    at it.eventitrapani.appaeventitp.ElencoMappaTutteCoseDaVedere.setUpMap(ElencoMappaTutteCoseDaVedere.java:269)
E/AndroidRuntime(10990):    at it.eventitrapani.appaeventitp.ElencoMappaTutteCoseDaVedere.setUpMapIfNeeded(ElencoMappaTutteCoseDaVedere.java:257)
E/AndroidRuntime(10990):    at it.eventitrapani.appaeventitp.ElencoMappaTutteCoseDaVedere.onCreate(ElencoMappaTutteCoseDaVedere.java:208)
E/AndroidRuntime(10990):    at android.app.Activity.performCreate(Activity.java:4470)
E/AndroidRuntime(10990):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
E/AndroidRuntime(10990):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
E/AndroidRuntime(10990):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
E/AndroidRuntime(10990):    at android.app.ActivityThread.access$600(ActivityThread.java:127)
E/AndroidRuntime(10990):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
E/AndroidRuntime(10990):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(10990):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(10990):    at android.app.ActivityThread.main(ActivityThread.java:4511)
E/AndroidRuntime(10990):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(10990):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(10990):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
E/AndroidRuntime(10990):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
E/AndroidRuntime(10990):    at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • 从问题/代码中仍然不清楚:您是在重复使用位图还是每次创建标记时都在解码新的位图?
  • 我正在为每个标记解码一个新标记,如何重复使用它们?

标签: android bitmap


【解决方案1】:

首先,为什么要从这样的资源中加载位图?您可以直接从您的资源getResources().getDrawable(R.drawable.blah) 中获得Drawable。如果您像这样检索 Drawable,它们都将共享底层位图,因此只有 N(其中 N 是您拥有的标记图标的数量)位图加载到内存中。

现在,如果您正在对可绘制对象应用一些转换,您可能需要先调用 mutate() 以获取具有单独状态的新可绘制对象(否则,如果您使一个透明对象全部变为透明)。

更新: 解决方案是使用直接使用资源ID而不是位图的标记图标初始化:

markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));

【讨论】:

  • 您好,首先感谢您的友好回复。好吧,我像这样检索可绘制对象,因为谷歌地图的标记需要位图格式的图标,并且无法将可绘制对象直接分配给标记。我没有对这些可绘制对象进行任何转换,我只有 6 种不同类别的标记和大约 450 个位置(教堂、纪念碑、博物馆、海滩、考古遗址和自然公园),我希望每个标记上出现适当的图标.第一次运行正常,第二次内存不足。
  • 不正确,您可以使用可绘制对象:markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));。它就在docs 的示例中
  • 无知是多么糟糕的事情!非常感谢你!你解决了我的问题!
  • getResources().getDrawable 导致内存泄漏
  • @Siddharth uuuhh.. 需要引用吗?
猜你喜欢
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-21
  • 1970-01-01
相关资源
最近更新 更多