2015-07-10 57 views
12

我將圖像從服務器加載到網格視圖中。爲此,我使用通用圖像加載器。我在適配器的getview()方法內使用圖像加載器。它需要來自arraylist &的圖像的URL從服務器加載圖像。圖像可以在100年代。我在一個片段中顯示網格視圖,因此每個片段都有一個單獨的網格視圖。當我長時間在多個片段之間切換時,我不再發生內存不足錯誤。如何在Android中使用imageloader釋放內存位圖?

建議的解決方案

  1. 釋放未使用的位圖。

因此,我使用第三方庫加載圖像。我只是在調用函數中傳遞圖像視圖,所以如何釋放位圖?

  • 製作堆大真清單中
  • 我想堆存儲器是動態&每當有增加存儲器垃圾收集器將釋放內存。

    3.使用UIL /畢加索/滑翔以避免內存泄漏

    4.Code

    private void unbindDrawables(View view) 
    { 
         if (view.getBackground() != null) 
         { 
           view.getBackground().setCallback(null); 
         } 
         if (view instanceof ViewGroup && !(view instanceof AdapterView)) 
         { 
           for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) 
           { 
             unbindDrawables(((ViewGroup) view).getChildAt(i)); 
           } 
           ((ViewGroup) view).removeAllViews(); 
         } 
    } 
    

    我已經在使用的第三釋放片段的onDestroy()方法()的存儲器黨的圖書館。

    這裏是我的gridViewAdapter類的代碼。

    @Override 
        public View getView(int position, View convertView, ViewGroup parent) { 
         final ViewHolder holder; 
         View view = convertView; 
         if (view == null) 
         { 
          view = inflater.inflate(R.layout.grid_item_photo, parent, false); 
          holder = new ViewHolder(); 
          holder.imageView = (ImageView) view.findViewById(R.id.imgLoader); 
          holder.play = (ImageView) view.findViewById(R.id.play); 
    
    
          view.setTag(holder); 
         } 
         else 
         { 
          holder = (ViewHolder) view.getTag(); 
         } 
         try{ 
         if(IMAGES_LIST.get(position).getType().equals("video")) 
         { 
         holder.play.setVisibility(View.VISIBLE); 
         } 
         else 
         { 
         holder.play.setVisibility(View.GONE); 
    
         } 
         ImageLoader.getInstance().displayImage(AppConst.BASE_IMAGE_URL+IMAGES_LIST.get(position).getThumbnail(), holder.imageView, options, new SimpleImageLoadingListener() { 
            @Override 
            public void onLoadingStarted(String imageUri, View view) { 
             view.setClickable(true); 
            } 
    
            @Override 
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) { 
             view.setClickable(true); 
    
            } 
    
            @Override 
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { 
             view.setClickable(false); 
    
            } 
           }, new ImageLoadingProgressListener() { 
            @Override 
            public void onProgressUpdate(String imageUri, View view, int current, int total) { 
    
            } 
           }); 
         }catch(Exception e) 
         { 
    
         } 
         catch(OutOfMemoryError e) 
         { 
    
         } 
         return view; 
        } 
        static class ViewHolder { 
         ImageView imageView,play; 
    
        } 
    
    
    } 
    
    +0

    在哪個Android版本上運行應用程序? – TechGuy

    +0

    @TechGuy andorid kitkat – Techiee

    +0

    我聽說內存管理是在每個Android版本上不同。並使用圖像緩存來提高性能。 – Hogun

    回答

    4

    呦可以在內存中緩存中刪除緩存圖像。使用MemoryCacheUtil爲:

    MemoryCacheUtils.removeFromCache(imageUrl, imageLoader.getMemoryCache()); 
    

    而且DiscCacheUtils進行刪除discCache

    DiscCacheUtils.removeFromCache(url, ImageLoader.getInstance().getDiscCache()); 
    

    此外,你可以清除內存高速緩存使用:

    imageLoader.clearMemoryCache(); 
    

    此外,您還可以控制內存和磁盤使用限制:

    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())   
         .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) 
         .discCache(new UnlimitedDiscCache(cacheDir)) 
    
    +0

    爲什麼會出現這個問題?@jiopez – Techiee

    +0

    我沒有對圖像進行處理,也沒有對磁盤進行緩存。 @jlopez – Techiee

    +0

    圖像緩存動態,以避免每次下載圖像 – jlopez

    1

    可能是這個原因是你只需要使用ImageLoader通過創建它的實例,以及我不知道DisplayImageOptions你had.Try更改選項設置,並檢查它out.For我這個選項可以幫助我加載在List的大圖像。

    在您的應用中試試這個選項。

    DisplayImageOptions imageOptions = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.ic_launcher).showImageOnFail(R.drawable.ic_launcher).resetViewBeforeLoading(true).cacheOnDisk(true).imageScaleType(ImageScaleType.EXACTLY).bitmapConfig(Bitmap.Config.RGB_565).considerExifParams(true).displayer(new FadeInBitmapDisplayer(3000, true, true, false)).build(); 
    
    6
    1. 這聽起來像你的碎片泄漏 - 您的片段留在他們的所有內容(包括位圖)內存,即使是的onDestroy叫。你可以使用MAT +堆轉儲查看究竟是什麼導致泄漏(有很多指南可用)。第一個犯罪嫌疑人應該是你從碎片中傳出「this」的碎片類別中的單身人士。作爲第一步,我會清除你的片段在onDestroy中的一切。

    2. 使「SimpleImageLoadingListener()」成爲一個內部靜態類,將您的片段保存爲WeakReference - 這可能會減少泄漏(或至少其中之一)。

    3. 你應該使用任何第三ImageLoader作爲一個單一的LRU緩存+一個磁盤緩存。你可以在這裏找到一些好的(Any best third party tool to cache image in Android?

    4. 在清單中的「largeHeap」根本就不在你的腦海裏。一旦你有泄漏,那麼你將有一個更大的堆填滿,直到OOM。

    1

    您可以嘗試避免內存緩存,並限制磁盤緩存。有關進一步優化,您可以檢查the source