2013-10-06 13 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()给出非空位图)。