null对象引用上的int org.json.JSONArray.length()

时间:2016-03-08 21:04:51

标签: android json android-volley

我正在使用volley库连接到服务器,我有一个Transaction类和一个带有以下代码的Server类:

反式:

public class Trans extends Server {
    public Object suggest(Context context) {
        return connect("xxxxxxx", Request.Method.GET);
    }
}

服务器:

public Object connect(String url, int method) {
    final Object[] object = {null};
    StringRequest postRequest;
    postRequest = new StringRequest(method, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    object[0] = response;
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                }
            }
    ) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            return params;
        }

        @Override
        public String getBodyContentType() {
            return "application/x-www-form-urlencoded; charset=UTF-8";
        }
    };
    int socketTimeout = 20000;
    RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
    postRequest.setRetryPolicy(policy);
    AppController.getInstance().addToRequestQueue(postRequest);
    return object[0];
}

但是当我试图用这个JSONArray时:

@Override
protected void onResume() {
    ArrayList<Suggests> arrayList = new ArrayList<>();
    JSONArray jsonArray = (JSONArray) trans.suggest(MainActivity.this);
    for (int i = 0; i < jsonArray.length(); i++) {
        try {
            JSONObject item = (JSONObject) jsonArray.get(i);
            Suggests suggests = new Suggests();
            suggests.title = item.getString("title");
            suggests.type = item.getString("type");
            arrayList.add(suggests);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    super.onResume();
}

申请人已关闭,我在logcat

中遇到此错误
java.lang.RuntimeException: Unable to resume activity {ir.aftabeshafa.shafadoc/ir.aftabeshafa.shafadoc.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length()' on a null object reference

问题是什么?我该如何解决?

1 个答案:

答案 0 :(得分:0)

取消评论中的建议,

步骤1 定义一个可传递所需结果的界面。 <T>是泛型类型,因此您可以返回所需的任何数据。您将在第2步中看到。

public interface AsyncResponse<T> {
    void onResponse(T response);
}

第2步更新Server和Trans类,将其作为参数

public class Server {

    public void connect(String url, int method, final AsyncResponse<String> asyncResponse) {
        StringRequest request = new StringRequest(method, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                if (asyncResponse != null) {
                    asyncResponse.onResponse(response);
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("VolleyError", error.getMessage());
                Log.e("VolleyError", new String(error.networkResponse.data));
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<String, String>();
                return params;
            }

            @Override
            public String getBodyContentType() {
                return "application/x-www-form-urlencoded; charset=UTF-8";
            }
        };

        int socketTimeout = 20000;
        RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        request.setRetryPolicy(policy);

        AppController.getInstance().addToRequestQueue(request);
    }
}

附带问题:你真的需要Context吗?它没有被使用......

public class Trans extends Server {
    public void suggest(Context context, AsyncResponse<String> asyncResponse) {
        connect("xxxxxxxx", Request.Method.GET, asyncResponse);
    }
}

第3步使用您的方法,以便在回调中获得结果。这是针对url http://jsonplaceholder.typicode.com/users进行测试的,它返回了10个User对象的JSONArray。

添加了ArrayAdapter作为完整示例,因为问题中的ArrayList似乎没有任何用处。

public class MainActivity extends AppCompatActivity {

    private ArrayList<User> arrayList;
    private Trans trans;
    private ArrayAdapter<User> adapter;
    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        trans = new Trans();
        arrayList = new ArrayList<User>();

        adapter = new ArrayAdapter<User>(MainActivity.this, android.R.layout.simple_list_item_1, arrayList);
        listView = (ListView) findViewById(android.R.id.list);
        listView.setAdapter(adapter);

    }

    @Override
    protected void onResume() {
        trans.suggest(MainActivity.this, new AsyncResponse<String>() {
            @Override
            public void onResponse(String response) {
                arrayList.clear(); // prevent duplicate data

                try {
                    // The URL that was tested returns a JSONArray
                    // Change to JSONObject, if necessary
                    JSONArray jsonArray = new JSONArray(response);

                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject item = (JSONObject) jsonArray.get(i);
                        User user = new User();
                        user.username = item.getString("name");
                        user.email = item.getString("email");
                        arrayList.add(user);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                // Notify since the arrayList has changed the adapter
                adapter.notifyDataSetChanged();
            }
        });

        super.onResume();
    }
}