My app has an activity with a ListView
, and for each cell in the list, I need to load an image from an URL. However, the app crashes when I add the line to load the image.
I don't know if the error is caused by my code or some cell-reuse-behavior of the List View, since the Logcat does not point to any line in my code. I made sure that the URLs passed are correct and may not interfere.
I followed this tutorial to write this code.
Here's the ListView
adapter class, where I load the imagem on getView(...)
:
class CellAdapter extends BaseAdapter {
Context context;
List<Product> productList;
private static LayoutInflater inflater = null;
public CellAdapter(Context context, List<Product> productList) {
this.context = context;
this.productList = productList;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return productList.size();
}
@Override
public Product getItem(int position) {
return productList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
while (view == null)
view = inflater.inflate(R.layout.product_result, null);
NetworkImageView image = (NetworkImageView) view.findViewById(R.id.cell_product_image);
image.setDefaultImageResId(R.drawable.image_placeholder);
image.setImageUrl(getItem(position).imageURL, APIManager.getSharedImageLoader());
return view;
}
}
The ImageLoader
used above is set up as follows:
sharedImageLoader = new ImageLoader(Volley.newRequestQueue(context), new BitmapLruCache());
And the BitmapLruCache
is:
public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache {
public BitmapLruCache() {
this(getDefaultLruCacheSize());
}
public BitmapLruCache(int sizeInKiloBytes) {
super(sizeInKiloBytes);
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
@Override
public Bitmap getBitmap(String url) {
return get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
public static int getDefaultLruCacheSize() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
return maxMemory / 8;
}
}
This is the Logcat error:
E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.android.volley.Request.<init>(Request.java:137)
at com.android.volley.toolbox.ImageRequest.<init>(ImageRequest.java:71)
at com.android.volley.toolbox.ImageLoader.get(ImageLoader.java:219)
at com.android.volley.toolbox.NetworkImageView.loadImageIfNecessary(NetworkImageView.java:149)
at com.android.volley.toolbox.NetworkImageView.onLayout(NetworkImageView.java:198)
at android.view.View.layout(View.java:7175)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:912)
at android.view.View.layout(View.java:7175)
at android.widget.ListView.setupChild(ListView.java:1833)
at android.widget.ListView.makeAndAddView(ListView.java:1748)
at android.widget.ListView.fillDown(ListView.java:670)
at android.widget.ListView.fillFromTop(ListView.java:727)
at android.widget.ListView.layoutChildren(ListView.java:1598)
at android.widget.AbsListView.onLayout(AbsListView.java:1262)
at android.view.View.layout(View.java:7175)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1130)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1047)
at android.view.View.layout(View.java:7175)
at android.widget.FrameLayout.onLayout(FrameLayout.java:343)
at android.view.View.layout(View.java:7175)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1130)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1047)
at android.view.View.layout(View.java:7175)
at android.widget.FrameLayout.onLayout(FrameLayout.java:343)
at android.view.View.layout(View.java:7175)
at android.widget.FrameLayout.onLayout(FrameLayout.java:343)
at android.view.View.layout(View.java:7175)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1140)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3714)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:853)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
at dalvik.system.NativeStart.main(Native Method)
Here is the method containing the null pointer exception:
public Request(int method, String url, Response.ErrorListener listener) {
mMethod = method;
mUrl = url;
mErrorListener = listener;
setRetryPolicy(new DefaultRetryPolicy());
/* the next line is line 137 with the Exception */
mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode();
}
You are using an out-of-date version of this library, which is missing the following two recent commits:
6c33917 Merge "Guard against NullPointerException currently occurring in Volley when a Request is given a url whose host is null." by Ficus Kirkpatrick - 3 weeks ago idea133-weekly-release master
0ec9297 Guard against NullPointerException currently occurring in Volley when a Request is given a url whose host is null. by kang - 3 weeks ago
Update your working version with git to reflect the current state of the project repository and you should be fine. Examining the diff for these, the change is basically adding and handling null checking.