0

I have been playing around with some JSON, trying to get and display the strings to show in a custom ListView with Textviews in my app. But I'm getting an NullPointerException when running. Can somebody tell me where I'm making a mistake and point me to a right direction maybe.

This is the JSON:

[{"id":"1","client_id":"1","client_name":"Company A"},{"id":"2","client_id":"2","client_name":"Company B"}]

this is the Model class:

public class Model {
    private String client_name;
    public String getClient_name() {
        return client_name;
    }
    public void setClient_name(String client_name) {
        this.client_name = client_name;
    }
}

Wrap class:

public class Wrap {
   private ArrayList<Model> models;

    public ArrayList<Model> getModels() {
        return models;
    }

    public void setModels(ArrayList<Model> models) {
        this.models = models;
    }
}

this is my Adapter:

public class Adapter extends ArrayAdapter<Model> {
    public Adapter(Context context, int resource) {
        super(context, resource);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;

        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.listview_item, null);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        final Model p = getItem(position);
        viewHolder.textone.setText(p.getClient_name());

        return convertView;
    }
}

The ViewHolder :

public class ViewHolder {
    public TextView textone;
    public ViewHolder(View convertView)
    {
       textone = (TextView)convertView.findViewById(R.id.txt_field);
    }
}

The url:

private static final String SO_URL = "http://www.example.com/webservice/?value";
private static final String PARAMS = "[{\"table\":\"locations\",\"operation\":\"select\"}]";

This is the AsyncTask's doInBackground method :

protected String doInBackground(Void... params) {
            try {
                //Create an HTTP client
               String  URL = URLEncoder.encode(PARAMS, "UTF-8");
                HttpClient client = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(SO_URL + URL);

                //Perform the request and check the status code
                HttpResponse response = client.execute(httpPost);
                StatusLine statusLine = response.getStatusLine();
                if(statusLine.getStatusCode() == 200) {
                    HttpEntity entity = response.getEntity();
                    InputStream content = entity.getContent();

                    try {
                        //Read the server response and attempt to parse it as JSON
                        Reader reader = new InputStreamReader(content);

                        Wrap wrap =  new Gson().fromJson(reader,Wrap.class);
                        for (Model model : wrap.getModels()) {
                            adapter.add(model);
                        }
                        adapter.notifyDataSetChanged();
                        content.close();
                    } catch (Exception ex) {
                        Log.e(TAG, "Failed to parse JSON due to: " + ex);
                        failedLoadingPosts();
                    }
                } else {
                    Log.e(TAG, "Server responded with status code: " + statusLine.getStatusCode());
                    failedLoadingPosts();
                }
            } catch(Exception ex) {
                Log.e(TAG, "Failed to send HTTP POST request due to: " + ex);
                failedLoadingPosts();
            }
            return null;

I'm getting this exception msg :

Failed to parse JSON due to: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.ArrayList com.bloomcore.dbnewapp.Wrap.getModels()' on a null object reference
kinsell
  • 338
  • 3
  • 4
  • 19

2 Answers2

1

OK, let's work through this logically...

When you get the exception you are seeing it is as a result of...

for (Model model : wrap.getModels()) {

...quite simply wrap is null, trying to call any method on a null object will through a NPE - no arguing about that - you didn't even need to show any other code to figure that one out.

So why is wrap null? Let's look at where it's instantiated (or at least where it SHOULD be)...

Wrap wrap =  new Gson().fromJson(reader,Wrap.class);

...so if after calling new Gson().fromJson(...) then wrap turns out to be null, why is that? Well obviously fromJson(...) is returning null.

So, assuming you've read the documentation for fromJson(...) (which I suspect you might not have done), when using a Reader, from the docs...

Returns:

an object of type T from the string. Returns null if json is at EOF.

...it seems your Reader is at EOF. So why would that be?

Basically the HttpResponse doesn't have an HttpEntity with any valid content. Either your server simply isn't returning anything full stop OR the HttpPost doesn't contain valid data in order for the server to return anything valid.

In other words, check your server code and if that's fine, check what you're posting.

Squonk
  • 48,735
  • 19
  • 103
  • 135
  • Thanks for the logical explanation, The server code is fine. And Im using the same field names in my Model, are you saying that the problem is in the url? im stuck here – kinsell Nov 25 '15 at 23:33
  • here is some more info, if it helps `SO_URL = "http://www.example.com/webservice/?value";` and `PARAMS = "=[{%22table%22:%20%22locations%22,%22operation%22:%20%22select%22,%22transactionCompleted%22:%20true}]";` – kinsell Nov 25 '15 at 23:34
0

You should make sure getModels() is not null when the Object is created. Some Json parsers only use lists but never create them.

private ArrayList<Model> models = new ArrayList<>();

I assume it's trying to add elements to the list which is null.

Till
  • 994
  • 5
  • 18