android - marcar - json google maps api
google maps api v2 error de memoria (3)
De acuerdo ... Creo que esto debería funcionar ...
Agrega googleMap.clear()
siempre que quieras restablecer el mapa.
Espero que esto te ayudará.
Tengo un gran problema de memoria en mi aplicación. Estoy usando google map api v2 con ClusterManager
y marcadores personalizados. proporciono una imagen a través de call a markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
para cada marcador basado en su categoría. el problema es: después de varias rotaciones de pantalla, mi aplicación se cuelga debido a un error 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.n.c.i.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.c.l.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.c.l.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.c.l.b(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.c.b.ak.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.c.b.as.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.x.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.l.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.l.b(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)
Tengo un objeto LruCache
con mis Bitmap
s, significa que no los vuelvo a crear, sino que los vuelvo a usar. Puedo ver claramente que cada objeto de Bitmap
se toma de la memoria caché, no de otro lado. Sin embargo, si el Bitmap
no está en el caché (cargando por primera vez), lo cargo desde el almacenamiento interno de mi aplicación, pero solo se agradece cuando se borra el Bitmap
bits la primera vez. LruCache
la instancia de LruCache
en una instancia de Fragment
retenida y la paso a mi objeto DefaultClusterRenderer<MyObject>
cada vez que se recrea la Activity
y se debe volver a dibujar el mapa.
esta es mi extensión 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);
}
}
este es el código dentro de mi Activity
donde empiezo a cargar el mapa (este código se ejecuta cada vez que cambia la orientación de la pantalla):
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);
la memoria sigue aumentando con cada rotación de pantalla, cuanto más amplío el mapa (cuantos más marcadores se muestren) más cantidad de memoria se agrega al montón de mi aplicación cuando giro la pantalla hasta que la aplicación falla.
a veces el error no es como el anterior, pero muestra que OOM sucedió en esta línea en mi extensión DefaultClusterRenderer<MyItam>
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
.
si desactivo el icono de marcador personalizado (elimino todo el código relacionado con Bitmap
), el problema de memoria desaparece. por favor, ayúdame a encontrar las causas de este OOM.
Me encontré con este problema tratando de ejecutar una aplicación en modo demostración durante unas horas a la vez. No importa lo que intenté, después de 30 minutos, vería este bloqueo sin un informe de pila legible.
Probé System gc (), separando el fragmento, actividades singleton, actualizando los servicios de google play a la última, borrando referencias a superposiciones, adjuntando el ciclo de vida del mapa a la actividad y lo que no. Después de muchos intentos fallidos y mucha frustración, finalmente encontré algo que funcionó. No es una solución para el error del mapa, pero impidió que mi aplicación se bloquee:
<application
...
android:largeHeap="true">
Este es el error de Google maps V2. Google resuelve algunos problemas. El problema de los errores está aquí
Para recuperar este problema, puede seguir estos pasos:
A XML le gustará esto:
<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" />
Tome ejemplo de Google Map: `` GoogleMap atmFinderMap;
Antes de inicializar el mapa, llame a
System.gc();
ygetMap (). clear (); `
if(GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()) == ConnectionResult.SUCCESS) { System.gc(); getMap().clear();}
establecer un mapa como este:
SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.frYourMap);
atmFinderMap = fragment.getMap();
Use este método sobrescrito:
@Override public void onLowMemory() { super.onLowMemory(); System.gc(); }
Para obtener más información puede ver esta respuesta