2015-08-04 5 views
0

Я создал приложение, в котором есть gridview, и когда мы выберем любую миниатюру, мы увидим изображение полного размера в viewpager. Но когда я нажимаю на миниатюру и много раз просматриваю изображение, я выхожу из памяти в android. Я много искал и нашел одно решение использовать пикассо вместо imageloader, но я не могу использовать picasso. Я делаю это только с помощью imageloader. Может кто-нибудь, пожалуйста, скажите мне точную конфигурацию и параметры для imageloader, чтобы я не выходил из памяти ????ImageLoader из памяти в Android

Пожалуйста, помогите, я попробовал много изменений конфигурации.

public class ImagePagerAdapter extends PagerAdapter { 
    LayoutInflater inflater; 
    PhotoViewAttacher attacher; 
    PhotoViewAttacher pic; 
    private DisplayImageOptions options; 
    List<Image> IMAGES_LIST = AppController.getInstance().getPrefManger() 
      .getImages(); 

    public ImagePagerAdapter(Context context) { 
     inflater = LayoutInflater.from(context); 
     options = new DisplayImageOptions.Builder() 
       .showImageForEmptyUri(R.drawable.ic_empty) 
       .showImageOnFail(R.drawable.ic_error) 
       .cacheOnDisc() 
       .imageScaleType(ImageScaleType.IN_SAMPLE_INT) 
       .build(); 
    } 

    @Override 
    public Object instantiateItem(ViewGroup container, final int position) { 
     final View imageLayout = inflater.inflate(
       R.layout.item_pager_image, container, false); 
     assert imageLayout != null; 
     pos = position; 
     imageView = (TouchImageView) imageLayout.findViewById(R.id.image); 
     imageView.setTag(position); 


     imageView.setOnDoubleTapListener(new OnDoubleTapListener() { 
      @Override 
      public boolean onSingleTapConfirmed(MotionEvent e) { 
       // TODO Auto-generated method stub 
       try 
       { 
       timer.cancel(); 
       } 
       catch(Exception ex){} 
       if(IMAGES_LIST.get(position).getType().equalsIgnoreCase("image")) 
       { 
       mHandler.removeCallbacks(r); 
       share.setVisibility(View.VISIBLE); 
       play.setVisibility(View.VISIBLE); 
       done.setVisibility(View.VISIBLE); 
       if (!isCopyImage.equals("yes")) { 
        gimmy.setVisibility(View.VISIBLE); 
       } 
       comment.setVisibility(View.VISIBLE); 
       count.setVisibility(View.VISIBLE); 
       caption.setVisibility(View.VISIBLE); 
       mHandler.postDelayed(r, 5 * 1000); 
       } 
       else{ 
        mHandler.removeCallbacks(r); 
        done.setVisibility(View.VISIBLE); 
        mHandler.postDelayed(r, 5 * 1000); 

       } 
       return false; 
      } 

      @Override 
      public boolean onDoubleTapEvent(MotionEvent e) { 
       // TODO Auto-generated method stub 
       Log.i("hello", ""); 
       return false; 
      } 

      @Override 
      public boolean onDoubleTap(MotionEvent e) { 
       // TODO Auto-generated method stub 
       return false; 
      } 
     }); 

     try{ 
     final ProgressBar spinner = (ProgressBar) imageLayout 
       .findViewById(R.id.loading); 
     final ImageView videoplay = (ImageView) imageLayout 
       .findViewById(R.id.play); 
     if(IMAGES_LIST.get(position).getType().equalsIgnoreCase("image")) 
     { 
      videoplay.setVisibility(View.INVISIBLE); 
      ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(container.getContext()); 
      config.memoryCache(new WeakMemoryCache()); 
      config.denyCacheImageMultipleSizesInMemory(); 
      config.discCache(new UnlimitedDiskCache(container.getContext().getCacheDir())); 
      imageLoader=ImageLoader.getInstance(); 
      imageLoader.init(config.build()); 
      imageLoader.displayImage(
       AppConst.BASE_IMAGE_URL 
         + IMAGES_LIST.get(position).getFileName(), 
       imageView, options, new SimpleImageLoadingListener() { 
        @Override 
        public void onLoadingStarted(String imageUri, View view) { 
         spinner.setVisibility(View.VISIBLE); 
         view.setVisibility(View.GONE); 
        } 

        @Override 
        public void onLoadingFailed(String imageUri, View view, 
          FailReason failReason) { 
         String message = null; 
         switch (failReason.getType()) { 
         case IO_ERROR: 
          message = "Input/Output error"; 
          break; 
         case DECODING_ERROR: 
          message = "Image can't be decoded"; 
          break; 
         case NETWORK_DENIED: 
          message = "Downloads are denied"; 
          break; 
         case OUT_OF_MEMORY: 
          message = "Out Of Memory error"; 
          break; 
         case UNKNOWN: 
          message = "Unknown error"; 
          break; 
         } 
         spinner.setVisibility(View.GONE); 
        } 

        @Override 
        public void onLoadingComplete(String imageUri, 
          View view, Bitmap loadedImage) { 
         spinner.setVisibility(View.GONE); 
         view.setVisibility(View.VISIBLE); 

        } 
       }); 

     container.addView(imageLayout, 0); 

     } 
+0

Это было задано (и ответили) [несколько] (http://stackoverflow.com/questions/10436927/out-of-memory-error-with-loading-image) [раз] (http: // stackoverflow .com/questions/541966/lazy-load-of-images-in-listview) уже, выполните поиск, и вы найдете ответ. – Sebastian

+0

Я использую imageloader not bitmap для загрузки изображений с URL-адреса, поэтому эти две приведенные вами ссылки не могут быть удалены –

+0

Если вы хотите получить ответ, сначала вы должны показать, что уже сделали. Включите некоторый код. StackOverflow не предназначен для людей, пишущих код для других, но просить о помощи после того, как вы попробовали и не смогли найти решение. – Sebastian

ответ

1

Важно, чтобы изображения обычно декодировались с использованием 3 или 4 байта на пиксель. Таким образом, изображение 5Mpx потребует 20 Мб, что часто больше, чем то, что ОС позволит вашему приложению на некоторых телефонах. Вы должны изменить параметры при загрузке изображения, чтобы уменьшить его при декодировании.

Ты прочитал (а) this? Существует множество предложений по устранению ошибок Out Of Memory.

Если вы часто получили OutOfMemoryError в вашем приложении с помощью универсального загрузчика Изображения затем:

  • Отключить кэширование в памяти. Если OOM все еще происходит, кажется, ваше приложение имеет утечку памяти. Используйте MemoryAnalyzer для его обнаружения. В противном случае выполните следующие шаги (все или несколько):

  • Уменьшите размер пула потоков в конфигурации (.threadPoolSize (...)). Рекомендуется 1 - 5.

  • Используйте .bitmapConfig (Bitmap.Config.RGB_565) в параметрах отображения. Растровые изображения в RGB_565 потребляют в 2 раза меньше памяти, чем в ARGB_8888.

  • Использование .imageScaleType (ImageScaleType.EXACTLY)

  • Используйте .diskCacheExtraOptions (480, 320, нуль) в конфигурации

+0

Да, я пробовал все, но не использовал –

+0

Я использую universalimageloader 1.9.4 –

+0

, используя эту конфигурацию. Я теряю память после загрузки 25- 26 images –

0

Я не верю, что это решит вашу проблему , но вы должны запустить ImageLoader в методе onCreate из вашего приложения (создать класс, который расширяет приложение и помещает информацию в манифест).

Вы также можете показать нам образец изображений, которые вы пытаетесь загрузить, использовать MemoryAnalyzer, чтобы найти то, что занимает столько памяти и, конечно же, следовать рекомендованным параметрам в этом случае (отключить кеш, imageScaleType ... Как сказано до)

2

ImageLoader не непосредственно ваша проблема; Основная проблема, с которой вы сталкиваетесь, - это неправильное управление растровыми изображениями.

Во-первых, вы не должны загружать новые растровые объекты для каждого экземпляра изображения, которое вам нужно. Это приводит ко многим распределениям в вашей растровой куче, и много блоков памяти заняты. Как описано в Re-using bitmaps Вы можете загружать новые растровые изображения в пространство памяти старых растровых изображений, которые больше не могут использоваться. Вы можете связать это с LRUCache, чтобы вы знали, какие изображения вам больше не нужны, и вы можете повторно использовать их память. Подумайте об этом процессе, очень близком к objectpools.

Во-вторых, убедитесь, что вы используете правильные пиксельные форматы изображений. Как описано в Smaller Pixel Formats с использованием формата RGB_565, вы сэкономите около 50% на пиксель в памяти, что идеально подходит для непрозрачных изображений, загружаемых из файлов JPG.

В-третьих, внимательно изучите распределения памяти, чтобы гарантировать, что ваши растровые объекты будут правильно освобождены. Если вы не освобождаете их должным образом, вы создаете new memory leak, который занимает память и не возвращает ее обратно в приложение.

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

Смежные вопросы