Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Ver buscapersonas con cargador de imágenes universal sin error de memoria

No estoy realmente seguro de si un ViewPager con Universal Image Loader puede / debe ser utilizado como una alternativa para una galería como la interfaz ya que me he encontrado con un error de memoria durante la carga de imágenes de la tarjeta SD y verlos en modo de pantalla completa. No importa cuál sea el número, funciona bien con un GridView, pero al ver las imágenes en el View Pager, cada mapa de bits sigue consumiendo mucha memoria y después de 10 o más imágenes, da el error de memoria.

He visto casi todas las preguntas que se han publicado aquí relacionadas con el error de memoria de fuera mientras se trabaja con el Universal Image Loader y en cada uno de ellos, ha habido un error de configuración como la causa.

  • Cómo hacer la imagen de fondo de la aplicación para Android repetir
  • DialogFragment setCancelable propiedad no funciona
  • Cambiar la fuente del texto de la pestaña en la compatibilidad con el diseño de Android TabLayout
  • Implementación de un control deslizante en Android
  • Cómo excluir un archivo cpp en gradle experimental?
  • Cuadro de diálogo personalizado sin título y borde
  • No sé si estoy usando las configuraciones equivocadas o qué, pero he perdido mucho tiempo en él y estoy un poco atascado, cualquier ayuda / asesoramiento sería apreciado.

    Las configuraciones para el ImageLoader:

    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()) .memoryCache(new WeakMemoryCache()) .denyCacheImageMultipleSizesInMemory() .discCacheFileNameGenerator(new Md5FileNameGenerator()) .imageDownloader(new ExtendedImageDownloader(getApplicationContext())) .tasksProcessingOrder(QueueProcessingType.LIFO) // .enableLogging() // Not necessary in common .build(); 

    Las opciones de visualización de la imagen son:

     options = new DisplayImageOptions.Builder() .showImageForEmptyUri(R.drawable.image_for_empty_url) .resetViewBeforeLoading() .imageScaleType(ImageScaleType.IN_SAMPLE_INT) .bitmapConfig(Bitmap.Config.RGB_565) .displayer(new FadeInBitmapDisplayer(300)) .build(); 

    Estoy utilizando el proyecto de ejemplo que se dio con la biblioteca, pero los ajustes no funcionará bien, sólo se bloquea después de algún tiempo. Mi conjetura es que hay una devolución de llamada específica donde tengo que reciclar mapas de bits de las vistas de que no son visibles.

    EDIT: Sé que es una fuga de memoria, las vistas que no son visibles se destruyen cuando deberían ser, pero la memoria no se libera como debería. Heres la implementación de la devolución de llamada destroyItem, siguió los consejos dados en diferentes preguntas, pero todavía no puede encontrar la fuga de memoria.

     @Override public void destroyItem(View container, int position, Object object) { // ((ViewPager) container).removeView((View) object); Log.d("DESTROY", "destroying view at position " + position); View view = (View)object; ((ViewPager) container).removeView(view); view = null; } 

  • ¿Cómo obtengo el contenido de la página web desde un WebView?
  • Integre una aplicación de Android (.apk) en un proyecto de Android existente
  • Entrada recursiva para ejecutarPendingTransactions
  • Recuperar el número de teléfono de la llamada entrante en Android
  • Recorte de visualización de Android
  • Android AutoCompleteTextView con chips
  • 7 Solutions collect form web for “Ver buscapersonas con cargador de imágenes universal sin error de memoria”

    Trate de aplicar las siguientes sugerencias:

    1. Use ImageScaleType.EXACTLY
    2. Habilitar el almacenamiento en caché en el disco (en las opciones de visualización).
    3. Finalmente intente utilizar .discCacheExtraOptions(maxImageWidthForDiscCache, maxImageHeightForDiscCache, CompressFormat.PNG, 0);

    Probablemente no sea la mejor aplicación para resolverlo, pero funcionó para mí. Eliminar las vistas de imagen no es suficiente, así que decidí reciclar mapas de bits en 'destroyItem':

     @Override public void destroyItem(ViewGroup container, int position, Object object) { View view = (View) object; ImageView imageView = (ImageView) view.findViewById(R.id.image); if (imageView != null) { Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); bitmap.recycle(); bitmap = null; } ((ViewPager) container).removeView(view); view = null; } 

    Esto no limpia las últimas 3 páginas activas cuando dejas la actividad, aunque espero que GC se encargue de ellas.

    Sólo publicar esto porque esta pregunta está llegando a Google en la búsqueda de UIL y OOP. Tenía problemas OOP no importa qué configuración, lo que resolvió todos mis problemas fueron las dos clases RecyclingImageView y RecyclingBitmapDrawable de este proyecto de ejemplo.

    También utilicé la misma biblioteca y tuve el mismo error. Como solución, he creado un sparseArray para mantener instancias de photoView. Y úsalo así:

      private SparseArray<PhotoView> photoViewHolder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... photoViewHolder = new SparseArray<PhotoView>(); ... } private class GalleryPagerAdapter extends PagerAdapter { @Override public View instantiateItem(ViewGroup container, int position) { PhotoView photoView = new PhotoView(container.getContext()); ImageHolder holder = new ImageHolder(); holder.position = position; holder.loaded = false; photoView.setTag(holder); photoViewHolder.put(position, photoView); // I used LazyList loading loader.DisplayImage(items.get(position), photoView); // Now just add PhotoView to ViewPager and return it container.addView(photoView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); return photoView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); photoViewHolder.remove(position); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } } 

    Y para manejar el oyente de viewPager:

      pager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageScrollStateChanged(int position) { } @Override public void onPageScrolled(int position, float arg1, int arg2) { } @Override public void onPageSelected(int position) { if(photoViewHolder.get(position) != null) { ImageHolder holder = (ImageHolder)photoViewHolder.get(position).getTag(); // Do something... } } }); 

    Espero que esto ayude…

    He utilizado la implementación de kutothe desde la página de problemas de github .

    Tuve este problema al configurar simplemente Uri a ImageView usando: iv.setImageURI(Uri.fromFile(imgFile)); Tuve el mismo problema con Universal Image Loader, e incluso busqué otros cargadores de imágenes por ahí, y encontré otra buena llamada " Picasso ", pero también tenía el mismo problema.

    Así que lo que funcionó para mí es usar GestureImageView y configurar gesture-image:recycle a true a través de XML y cargar las imágenes con el siguiente código:

      Drawable yourDrawable = null; try { InputStream inputStream = getActivity().getContentResolver().openInputStream(Uri.fromFile(img)); yourDrawable = Drawable.createFromStream(inputStream, Uri.fromFile(img).toString() ); inputStream.close(); } catch (FileNotFoundException e) { yourDrawable = getResources().getDrawable(R.drawable.ic_launcher); } catch (IOException e) { e.printStackTrace(); } if (yourDrawable != null) iv.setImageDrawable(yourDrawable); 

    La razón por la que se bloqueaba y dando error de OOM es que los mapas de bits no se reciclan cuando la imagen no se muestran en la pantalla más, por lo tanto, se produce una pérdida de memoria.

    Si hay otra forma de reciclar el mapa de bits en el ImageView normal, sería una mejor solución.

    Espero haber ayudado.

    Sé que es tarde, pero quizás mi respuesta ahorrará tiempo a alguien. Después de horas y horas de tratar de resolver este problema (con casi todas las respuestas encontradas en el desbordamiento de la pila) finalmente lo resolví con la biblioteca de imágenes de Fresco. It'a lib escrito por Facebook y su objetivo principal es utilizar la memoria de manera eficiente. Es realmente genial y mi error de memoria desapareció. Recomiendo encarecidamente su uso.

    http://frescolib.org/

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.