Google maps api v2 ошибка памяти

У меня огромная проблема с памятью в моем приложении. Я использую google map api v2 с помощью ClusterManager и настраиваемых маркеров. Я поставляю изображение по вызову markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap)); Для каждого маркера на основе его категории. Проблема в следующем: после нескольких поворотов экрана мое приложение вылетает из-за ошибки OOM:

 05-14 11:04:12.692 14020-30201/rokask.rideabike E/art﹕ Throwing OutOfMemoryError "Failed to allocate a 4194316 byte allocation with 1627608 free bytes and 1589KB until OOM" 05-14 11:04:12.722 14020-30201/rokask.rideabike E/AndroidRuntime﹕ FATAL EXCEPTION: GLThread 19179 Process: rokask.rideabike, PID: 14020 java.lang.OutOfMemoryError: Failed to allocate a 4194316 byte allocation with 1627608 free bytes and 1589KB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.Bitmap.nativeCreate(Native Method) at android.graphics.Bitmap.createBitmap(Bitmap.java:939) at android.graphics.Bitmap.createBitmap(Bitmap.java:912) at android.graphics.Bitmap.createBitmap(Bitmap.java:879) at com.google.maps.api.android.lib6.gmm6.ncia(Unknown Source) at com.google.maps.api.android.lib6.gmm6.ncla(Unknown Source) at com.google.maps.api.android.lib6.gmm6.ncla(Unknown Source) at com.google.maps.api.android.lib6.gmm6.nclb(Unknown Source) at com.google.maps.api.android.lib6.gmm6.ncbak.a(Unknown Source) at com.google.maps.api.android.lib6.gmm6.ncbas.a(Unknown Source) at com.google.maps.api.android.lib6.gmm6.nxa(Unknown Source) at com.google.maps.api.android.lib6.gmm6.nla(Unknown Source) at com.google.maps.api.android.lib6.gmm6.nlb(Unknown Source) at com.google.maps.api.android.lib6.gmm6.n.cv.f(Unknown Source) at com.google.maps.api.android.lib6.gmm6.n.cv.run(Unknown Source) 

У меня есть объект LruCache с моим Bitmap s, это значит, что я не воссоздаю их, а повторно их использую. Я могу ясно видеть, что каждый объект Bitmap берется из кеша, а не из другого места. Однако, если Bitmap еще не загружен в кеш (загрузка первого раза), я загружаю его из внутреннего хранилища моего приложения, но это происходит только тогда, когда битмап в первый раз зашифрован. Я сохраняю экземпляр LruCache в сохраненном экземпляре Fragment и LruCache его в свой пользовательский объект DefaultClusterRenderer<MyObject> каждый раз, когда Activity воссоздана, а карта должна быть перерисована.

Это мое расширение DefaultClusterRenderer<MyItem> :

 public class DotRenderer extends DefaultClusterRenderer<Dot> { private final String internalStorageDir; private final LruCache<String, Bitmap> lruCache; public DotRenderer(Context context, GoogleMap googleMap, ClusterManager<Dot> clusterManager, LruCache<String, Bitmap> lruCache, String internalStorageDir) { super(context, googleMap, clusterManager); //this.bitmaps = bitmaps; this.internalStorageDir = internalStorageDir; this.lruCache = lruCache; } @Override protected void onBeforeClusterItemRendered(Dot mapObject, MarkerOptions markerOptions) { markerOptions.title(mapObject.getTitle()); String id = Integer.toString(mapObject.getTypeId()); // Bitmap bitmap = getBitmapFromMemCache(id); if (bitmap == null) { Log.d(MainActivity.LOG_TAG, "reading bitmap from storage."); Map.Entry<String, Bitmap> bitmapEntry = BitmapManager.getBitmapFromStorage(internalStorageDir, id); if (bitmapEntry != null) { markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmapEntry.getValue())); addBitmapToMemCache(id, bitmapEntry.getValue()); } } else { Log.d(MainActivity.LOG_TAG, "reading bitmap from cache."); markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap)); } } private void addBitmapToMemCache(String key, Bitmap bitmap) { if (getBitmapFromMemCache(key) == null) { lruCache.put(key, bitmap); } } private Bitmap getBitmapFromMemCache(String key) { return lruCache.get(key); } } 

Это код внутри моей Activity где я начинаю загружать карту (этот код выполняется каждый раз при изменении ориентации экрана):

  ClusterManager<Dot> clusterManager = new ClusterManager<>(this, googleMap); clusterManager.setOnClusterItemInfoWindowClickListener( new ClusterManager.OnClusterItemInfoWindowClickListener<Dot>() { @Override public void onClusterItemInfoWindowClick(Dot dot) { int id = dot.getId(); String title = dot.getTitle(); Log.d(LOG_TAG, "clicked marker with id " + id + " and title " + title + "."); Intent infoWindowActivityIntent = new Intent(MainActivity.this, InfoWindowActivity.class); infoWindowActivityIntent.putExtra("dotId", id); infoWindowActivityIntent.putExtra("dotTitle", title); startActivity(infoWindowActivityIntent); } }); googleMap.setOnCameraChangeListener(clusterManager); googleMap.setOnInfoWindowClickListener(clusterManager); DotRenderer dotRenderer = new DotRenderer(getApplicationContext(), googleMap, clusterManager, lruCache, this.getFilesDir().toString()); clusterManager.setRenderer(dotRenderer); 

Память увеличивается с каждым поворотом экрана, чем больше я масштабирую карту (чем больше маркеров отображается), тем больше объема памяти добавляется в кучу моего приложения, когда я поворачиваю экран до тех пор, пока приложение не выйдет из строя.

Иногда ошибка не похожа на приведенную выше, но показывает, что OOM произошла в этой строке в моем DefaultClusterRenderer<MyItam> markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap)); ,

Если я отключу значок пользовательского маркера (удалите весь код, связанный с Bitmap ), проблема с памятью исчезнет. Пожалуйста, помогите мне найти причину появления этого OOM.

Я столкнулся с этой проблемой, пытаясь запустить приложение в демонстрационном режиме в течение нескольких часов за раз. Независимо от того, что я пробовал, через 30 минут я увижу этот сбой без отчетного отчета о стеке.

Я попробовал систему gc (), отделив фрагмент, действия Singleton, обновив сервисы google play до последней, очистив ссылки на наложения, привязав жизненный цикл карты к активности, а что нет. После многих неудачных попыток и большого разочарования я наконец нашел что-то, что сработало. Это не ошибка для ошибки карты, но она не позволяет моему приложению сбой:

  <application ... android:largeHeap="true"> 

Хорошо … Я думаю, что это должно сработать …

Добавьте googleMap.clear() когда вы хотите сбросить карту.

Надеюсь, что это поможет вам.

Это ошибка Google maps V2. Google разрешает проблему. Проблема с ошибкой здесь

Чтобы восстановить эту проблему, вы можете выполнить следующие действия:

XML понравится:

 <fragment android:id="@+id/frYourMap" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" class="com.google.android.gms.maps.SupportMapFragment" /> 

Возьмите экземпляр Карты Google: `` GoogleMap atmFinderMap;

  1. Перед инициализацией вызова карты System.gc(); а также GetMap () ясно ();. `

     if(GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()) == ConnectionResult.SUCCESS) { System.gc(); getMap().clear();} 

Установить карту следующим образом:

 SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.frYourMap); atmFinderMap = fragment.getMap(); 
  1. Используйте этот перезаписанный метод:

     @Override public void onLowMemory() { super.onLowMemory(); System.gc(); } 

Чтобы получить дополнительную информацию, вы можете увидеть этот ответ

Intereting Posts
Какой андроид: inputType следует использовать для ввода IP-адреса? Очистка всех кэшированных элементов, созданных WebView? Свяжите массив строк в масляном ноже Как сделать «fastScrollEnabled» как ListView в ScrollView? Проблемы с эмулятором Android. Не обновляет изменения в xml-файлах Android – Phonegap – Конверсия в формат Dalvik завершилась с ошибкой 1 Проблема с разработкой GearVR после экспорта в виде Google Android Project Android: сохранить несколько экземпляров активности в фоновом стеке Добавить объект в ArrayList по указанному индексу Как создать активность настроек для Android Live Wallpaper ActionBarSherlock – удалите значок приложения в представлении действий (и других проблемах с дизайном) Вызывает ли View.removeAllViews () выпуск памяти? Отсутствующие кнопки в AlertDialog | Android 7.0 (Nexus 5x) Как я могу получить значение счетчика webkit-column-count и текущую страницу или идентификатор столбца? Как избежать множественных триггеров в EditText во время ввода пользователем?