2013-10-06 37 views
5

在我的應用程序中,我使用了抽象imageLoader,但有一個問題我無法理解。 當我只調用response.getBitmap並將其設置爲背景圖像時,它很好,但是當我爲示例System.out.println(response.getBitmap)添加一些代碼時,它會崩潰。總之,如果我只需調用respone.getBitmap就可以了,但是如果兩次或更多次崩潰。這裏有什麼問題?排隊圖像位圖爲空

public class NewsAdapter extends BaseAdapter { 
    private ArrayList<News> mNewsList; 
    private DefaultActivity mActivity; 
    private ImageLoader imageLoader; 
    private RequestQueue mRequestQueue; 

    public NewsAdapter(DefaultActivity pActivity, ArrayList<News> newsList){ 
     mActivity = pActivity; 
     mNewsList = newsList; 
     mRequestQueue = Volley.newRequestQueue(mActivity); 
     imageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache(
       BitmapLruCache.getDefaultLruCacheSize())); 

    } 

    private class ViewHolder { 
     public ImageView networkImageView; 
     public TextView title; 
     public TextView description; 
    } 

    @Override 
    public int getCount() { 
     return mNewsList.size(); 
    } 

    @Override 
    public News getItem(int i) { 
     return mNewsList.get(i); 
    } 

    @Override 
    public long getItemId(int i) { 
     return 0; 
    } 

    @Override 
    public View getView(int i, View view, ViewGroup viewGroup) { 
     final ViewHolder viewHolder; 
     final News news = getItem(i); 

     if (view == null){ 
      final LayoutInflater li = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      view = li.inflate(R.layout.orange_news_item, viewGroup, false); 
      viewHolder = new ViewHolder(); 
      viewHolder.networkImageView = (ImageView)view.findViewById(R.id.imageView); 
      viewHolder.title = (TextView)view.findViewById(R.id.title); 
      viewHolder.description = (TextView)view.findViewById(R.id.description); 

      view.setTag(viewHolder); 
     } else { 
      viewHolder = (ViewHolder) view.getTag(); 
     } 
     viewHolder.title.setText(Html.fromHtml(news.getTitle())); 
     viewHolder.description.setText(Html.fromHtml(news.getBody())); 
     imageLoader.get(news.getImageThumbUrl(),new ImageLoader.ImageListener() { 
      @Override 
      public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) { 
        viewHolder.networkImageView.setImageBitmap(response.getBitmap()); 
        System.out.println("bitmap="+response.getBitmap()); 
        System.out.println("width="+response.getBitmap().getWidth()); 
        System.out.println("height="+response.getBitmap().getHeight()); 
      } 

      @Override 
      public void onErrorResponse(VolleyError error) { 
       //To change body of implemented methods use File | Settings | File Templates. 
      } 
     }); 


     return view; 
     } 

} 
+0

什麼是崩潰? –

回答

3

我給幾個建議,你可以檢查你的代碼:

  • 一旦onResponse被調用,檢查位圖的null,因爲它可以null

    Bitmap bitmap = response.getBitmap(); 
    if (bitmap != null) { 
        //TODO other code is here 
    } 
    
  • 您也可以通過添加new BitmapLruCache()

    來激活緩存
    RequestQueue mRequestQueue = Volley.newRequestQueue(this); 
    imageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache()); 
    

你可以得到BitmapLruCache實現here

  • new BitmapLruCache()您可以檢查(調試或日誌)的位圖的存儲方式以及它們是如何從緩存

    @Override 
    public Bitmap getBitmap(String url) { 
        return get(url); //debug or log 
    } 
    
    @Override 
    public void putBitmap(String url, Bitmap bitmap) { 
        if (bitmap != null) { 
         put(url, bitmap); 
        } 
    } 
    

檢索如果問題仍然在這裏,請添加更多的信息。

+2

優秀的答案!我唯一的問題是爲什麼位圖可以在'onResponse'方法中爲空?我的理解是,它還沒有完全加載,但是,我怎麼知道它會在什麼時候?其實他們是2個問題;)。 – acrespo

+0

@acrespo差不多一年後,但你仍然可能對我剛剛添加的答案感興趣。 – jmacedo

+1

我發現它的效果更好,還可以在緩存實現中將'bitmap!= null'添加到'put'到'putBitmap()'的調用中。它可能會使錯誤圖像嘗試不必要地重新加載 - 但是如果沒有空值檢查,有時它會在加載完整的位圖時緩存一個空位圖,如果您給它時間來完成請求。 –

8

作爲除了validcat的回答是:

onResponse()爲您提供了一個即時響應一個空的位圖時,它開始獲取圖像,如果圖像是不是在ImageLoader的高速緩存。稍後,如果一切正常,則再次調用它,這次使用非空位圖。

這允許您在圖像加載時(onResponse()給出立即空值)設置加載屏幕或進度條,並在接收到屏幕時設置獲取的圖像(onResponse()給出非空位圖)。