Volley image bitmap is null
Asked Answered
P

2

5

In my application I am using volley imageLoader but there is one issue there I couldn't understand. When I am calling only response.getBitmap and set it as background imageview it's fine, but when I add some code for example System.out.println(response.getBitmap) it crashes. In one word if I call respone.getBitmap only once it's ok, but when twice or more it crashes. What is the problem here?

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;
      }

}
Prefabricate answered 6/10, 2013 at 13:0 Comment(0)
S
9

As an addition to validcat's answer:

onResponse() gives you a null bitmap with an immediate response when it starts to fetch the image and if the image is not in the ImageLoader cache. Later, if everything goes ok, it is invoked again, this time with a non null bitmap.

This allows you to setup a loading screen or progress bar while the image is loading (when onResponse() gives an immediate null) and set the fetched image on the screen when it is received (onResponse() gives a non null bitmap).

Stereotomy answered 17/2, 2015 at 2:33 Comment(0)
C
3

I give a few advices and you can check your code:

  • Once onResponse is called, check bitmap for a null, cause it can be null

    Bitmap bitmap = response.getBitmap();
    if (bitmap != null) {
         //TODO other code is here 
    }
    
  • As well you could activate caching by adding new BitmapLruCache()

    RequestQueue mRequestQueue = Volley.newRequestQueue(this);
    imageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache());
    

You can get BitmapLruCache realization here.

  • In new BitmapLruCache() you can check (debug or log) how bitmaps are stored and how they are retrieved from the cache

    @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);
        } 
    }
    

If problem is still here, pls add more info.

Cubiculum answered 17/10, 2013 at 13:46 Comment(3)
Excellent answer! My only question is Why can bitmap be null in the onResponse method? My understanding is that it isn't fully loaded yet, but then, how can i know when it will be? Actually they were 2 questions ;).Lantha
@Lantha Almost a year later, but you still might be interested in the answer I just added.Stereotomy
I found it works better to also add a bitmap != null check around the call to put in putBitmap() in the cache implementation. It may make error images try to reload unnecessarily—but without the null check there too, sometimes it caches an empty bitmap when it would load a full one if you give it time to finish the request.Ignite

© 2022 - 2024 — McMap. All rights reserved.