Outofmemeoryerror (viewpager + visiones de imagen)
Estoy mostrando más de 150 imágenes en viewpager, cuando el tamaño de la página cruzada 70 aplicación se está estrellando, todas las imágenes se cargan de la red, y he fallowed [enlace]: Extraño problema de memoria durante la carga de una imagen a un objeto Bitmap
Y lo estoy reciclando cada vez que la página que golpea alcanza 4,
- Uso del botón backstack y back en viewpager
- Android: Picasso no carga algunas imágenes
- La vista de Fragmento de ViewPager se pierde cuando el fragmento padre de ViewPager se oculta y luego se muestra
- El relleno de la barra de estado de CoordinatorLayout desaparece de ViewPager 2ª página
- Android TabHost dentro de Fragmento
Para aplicaciones de 70 páginas con 200 MB de memoria.
Necesito ayuda de usted, cómo manejarlo
Tengo que mostrar todas las páginas con swiping …
También he utilizado Runtime.getRuntime (). Gc ();
Es cualquier forma de liberar memoria si la memoria de la aplicación llega a los 50+ MB
gracias por adelantado
- Efecto de desplazamiento con múltiples visualizadores
- Android Master / Detalle de flujo dentro de ViewPager
- ViewPager con Fragmentos dentro de PopupWindow (o DialogFragment) - Error no se encontró ninguna vista para id para el fragmento
- Android ViewPager + Webview, ClassCastException! Necesita una vista web en un viewpager
- Cómo saber cuando Fragmento se vuelve invisible
- FragmentStatePagerAdapter fuga de memoria (fragmentos anidados con viewpager)
- OnPrepareOptionsMenu no se llama
- Cómo colocar el botón de acción flotante exclusivamente en un fragmento sólo en el diseño de la pestaña
La solución completa se puede encontrar a continuación, las líneas importantes son las del método destroyItem:
private class ContentPagerAdapter extends PagerAdapter { @Override public void destroyItem(View collection, int position, Object o) { View view = (View)o; ((ViewPager) collection).removeView(view); view = null; } @Override public void finishUpdate(View arg0) { // TODO Auto-generated method stub } @Override public int getCount() { return ids.length; } @Override public Object instantiateItem(View context, int position) { ImageView imageView = new ImageView(getApplicationContext()); imageView.findViewById(R.id.item_image); imageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), ids[position])); ((ViewPager) context).addView(imageView); return imageView; } @Override public boolean isViewFromObject(View view, Object object) { return view==((ImageView)object); } @Override public void restoreState(Parcelable arg0, ClassLoader arg1) { // TODO Auto-generated method stub } @Override public Parcelable saveState() { // TODO Auto-generated method stub return null; } @Override public void startUpdate(View arg0) { // TODO Auto-generated method stub }
Creo que esto sucede porque tienes una pérdida de memoria, revisa tus variables, no usas static vars para nada grande, usa final cuando es posible, convierte a todos los miembros en privados.
Le sugiero que realice un commit (o guarde su código actual) y luego intente hacer lo que le pedí y ver si lo arregla.
Un ejemplo de código me permite decirle si tiene fugas de memoria, tal vez puede publicar el código en algún lugar como en github o código de google
En pocas palabras: usted podría estar haciendo todo bien, pero una variable todavía tiene una referencia a sus imágenes para que el recolector de basura no puede tocarlos.
Sé que diciendo que tienes una pérdida de memoria duele, pero por favor no te alarmes esto sucede a lo mejor de lo mejor, porque es tan fácil de suceder.
NOTA: No importa lo grande que los datos que carga desde aplicaciones de red nunca necesitaban más que el tamaño de un archivo si se maneja correctamente.
Gracias
Sheetal,
Después de haber mirado su código puede intentar lo siguiente:
@Override public void destroyItem(View collection, int position, Object o) { Log.d("DESTROY", "destroying view at position " + position); View view = (View) o; ((ViewPager) collection).removeView(view); view = null; }
Esto debería liberar el imageView para la recolección de basura.
¿Está cargando sus imágenes en el método de vista onCreateView ()?
El marco parece ocuparse de los requisitos de gestión de memoria al hacerlo de esta manera. Había intentado cargar mis imágenes en mi FragmentPageAdapter que las pasaba en mi constructor del fragmento precargado o como parte del método del instaniateItem del fragmento pero éstos ambos me dieron el problema que usted está haciendo frente. Al final pasé la información necesaria para cargar cada imagen en el constructor Fragmento y luego usé estos detalles en el método onCreateView ().
marca
Sheetal,
No tengo mi código delante de mí en el minuto pero debe ser algo similar al siguiente:
public class MyFragment extends Fragment { private Resources resources; // I load my images from different resources installed on the device private int id; public MyFragment() { setRetainInstance(true); // this will prevent the app from crashing on screen rotation } public MyFragment(Resources resources, int id) { this(); // this makes sure that setRetainInstance(true) is always called this.resources = resources; this.id = id; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ImageView imageView = (ImageView)inflater.infale(R.layout.fragmentview, container, false); imageView.setImageBitmap(BitmapFactory.decodeResource(resources, id)); return imageView; } }
Esto es más o menos de la parte superior de mi cabeza, por lo que podría no ser exacta, pero es bastante cerca.
Si necesita más ayuda simplemente grita, no olvide marcar esta respuesta como si le hubiera ayudado :).
Sheetal,
Según lo solicitado, utilizo el código anterior como sigue:
En mi FragmentActivity hago lo siguiente en el método onCreate ():
pager = (ViewPager)findViewById(R.id.pager); imageAdapter = new MyPagerAdapter(this, pager, theResources, listOfIds.pageBitMapIds); imageAdapter.setRecentListener(this); pager.setAdapter(imageAdapter);
Entonces en mi PagerAdapter hago lo siguiente:
@Override public Object instantiateItem(ViewGroup container, int position) { MyFragment myFragment = new MyFragment(resources, resourceIds[position], recentListener, position); myFragments[position] = myFragment; return super.instantiateItem(container, position); } @Override public Fragment getItem(int position) { return myFragments[position]; }
Y luego utilizo el código en mi anterior respuesta anterior.
Esto obviamente no es código completo y se ha adaptado de mi código real, pero debe darle una buena idea de qué hacer y dónde hacerlo.
marca