Reputation: 357
I have a ListView
that is populated by a JSONArray
. The data loads, but when I attempt to scroll, it crashes
Logcat:
09-19 11:50:53.512 15110-15110/io.moffat.kitchenpal E/InputEventReceiver﹕ Exception dispatching input event.
09-19 11:50:53.513 15110-15110/io.moffat.kitchenpal E/MessageQueue-JNI﹕ Exception in MessageQueue callback: handleReceiveCallback
09-19 11:50:53.514 15110-15110/io.moffat.kitchenpal E/MessageQueue-JNI﹕ java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:591)
at com.pkmmte.view.CircularImageView.refreshBitmapShader(CircularImageView.java:341)
at com.pkmmte.view.CircularImageView.invalidate(CircularImageView.java:262)
at android.widget.ImageView.setImageDrawable(ImageView.java:456)
at com.squareup.picasso.PicassoDrawable.setPlaceholder(PicassoDrawable.java:61)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:664)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:601)
at io.moffat.kitchenpal.RecipeAdapter.getView(RecipeAdapter.java:87)
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.makeAndAddView(ListView.java:1864)
at android.widget.ListView.fillDown(ListView.java:698)
at android.widget.ListView.fillGap(ListView.java:662)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4991)
at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3418)
at android.widget.AbsListView.onTouchMove(AbsListView.java:3801)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3632)
at android.view.View.dispatchTouchEvent(View.java:8471)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59)
at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
at android.view.View.dispatchPointerEvent(View.java:8666)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5807)
at android.view.ViewRootImpl.doPr
09-19 11:50:53.516 15110-15110/io.moffat.kitchenpal E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: io.moffat.kitchenpal, PID: 15110
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:591)
at com.pkmmte.view.CircularImageView.refreshBitmapShader(CircularImageView.java:341)
at com.pkmmte.view.CircularImageView.invalidate(CircularImageView.java:262)
at android.widget.ImageView.setImageDrawable(ImageView.java:456)
at com.squareup.picasso.PicassoDrawable.setPlaceholder(PicassoDrawable.java:61)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:664)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:601)
at io.moffat.kitchenpal.RecipeAdapter.getView(RecipeAdapter.java:87)
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.makeAndAddView(ListView.java:1864)
at android.widget.ListView.fillDown(ListView.java:698)
at android.widget.ListView.fillGap(ListView.java:662)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4991)
at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3418)
at android.widget.AbsListView.onTouchMove(AbsListView.java:3801)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3632)
at android.view.View.dispatchTouchEvent(View.java:8471)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59)
at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
at android.view.View.dispatchPointerEvent(View.java:8666)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl.deliverInputEv
Activity with the Listview
class Populate extends AsyncTask<String, String, JSONArray> {
protected void onPreExecute() {
progress = ProgressDialog.show(RecipeSearch.this, "Finding Recipes", "Searching....", true);
}
@Override
protected JSONArray doInBackground(String... urls) {
JSONParser recipeParse = new JSONParser();
String rawJSON = recipeParse.getJSON(urls[0]);
try {
if (rawJSON != null) {
JSONObject object = new JSONObject(rawJSON);
JSONArray jArray = object.getJSONArray("recipes");
return jArray;
} else {
JSONArray jArray = null;
return jArray;
}
} catch(Exception e) {
System.out.println(e);
Toast.makeText(getApplicationContext(), "Error Searching for Recipes",
Toast.LENGTH_SHORT).show();
JSONArray jArray = null;
return jArray;
}
//do http request and add objects to array here.
//need to do a custom adapter
// return null;
}
@Override
protected void onPostExecute(JSONArray jArray) {
if (jArray != null) {
final ListView recipes = (ListView) findViewById(R.id.recipeView);
recipes.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
JSONObject selected = (JSONObject) (recipes.getItemAtPosition(position));
String url = null;
try {
url = selected.getString("source_url");
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT).show();
}
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
recipeAdapter = new RecipeAdapter(RecipeSearch.this, jArray);//jArray is your json array
recipes.setAdapter(recipeAdapter);
} else {
Toast.makeText(getApplicationContext(), "No Recipes Found", Toast.LENGTH_SHORT).show();
finish();
}
progress.dismiss();
}
}
Adapter
public class RecipeAdapter extends BaseAdapter implements ListAdapter {
private final Activity activity;
private final JSONArray jsonArray;
public RecipeAdapter (Activity activity, JSONArray jsonArray){
assert activity !=null;
assert jsonArray != null;
this.jsonArray = jsonArray;
this.activity = activity;
}
@Override
public int getCount(){
if(null==jsonArray)
return 0;
else
return jsonArray.length();
}
@Override
public JSONObject getItem(int position){
if(null==jsonArray) return null;
else
return jsonArray.optJSONObject(position);
}
@Override
public long getItemId(int position){
return 0;
}
@Override
public View getView (int position, View v, ViewGroup parent){
if (v == null) {
v = View.inflate(activity, R.layout.recipe_item, null);
}
CircularImageView icon = (CircularImageView)v.findViewById(R.id.recipeIcon);
TextView title = (TextView) v.findViewById(R.id.recipeTitle);
TextView supplier = (TextView) v.findViewById(R.id.supplier);
JSONObject JSdata = getItem(position);
if(null!=JSdata){
try {
if (JSdata.has("title")) {
title.setText(JSdata.getString("title"));
}
if (JSdata.has("publisher")) {
supplier.setText(JSdata.getString("publisher"));
}
if (JSdata.has("image_url")){
String image = JSdata.getString("image_url");
if (image != null) {
Picasso.with(activity)
.load(image)
.centerCrop()
.resize(50, 50)
.into(icon);
}
} else {
Toast.makeText(activity, "Image not loaded",
Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
ImageView fav = (ImageView)v.findViewById(R.id.favbutton);
fav.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(activity, "Fav",
Toast.LENGTH_SHORT).show();
}
});
return v;
}
}
I can't figure out why it's crashing. I assumed it was a JSON error based on similar questions, so I put in conditional checks to make sure that the JSONObject had the fields I was looking for.
Upvotes: 0
Views: 454
Reputation: 9047
It's actually not a JSONException
. As you can see in Logs there is null reference to a Bitmap
which upon calling getWidth
throws an exception.
The only place I can see this can occur is in the following line:
Picasso.with(activity)
.load(image)
.centerCrop()
.resize(50, 50)
.into(icon);
You should check if you're feeding a valid url to Picasso
cause if not, Picasso will throw an exception.
Upvotes: 1