Android null对象引用上的int org.json.JSONArray.length()
我正在使用volley库连接到服务器,我有一个事务类和一个服务器类,代码如下: 反式:Android null对象引用上的int org.json.JSONArray.length(),android,json,android-volley,Android,Json,Android Volley,我正在使用volley库连接到服务器,我有一个事务类和一个服务器类,代码如下: 反式: public class Trans extends Server { public Object suggest(Context context) { return connect("xxxxxxx", Request.Method.GET); } } 服务器: public Object connect(String url, int method) { fina
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];
}
应用程序强制关闭,我在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定义一个将传递所需结果的接口。
是一种泛型类型,因此您可以返回所需的任何数据。您将在步骤2中看到这一点
public interface AsyncResponse<T> {
void onResponse(T response);
}
步骤3使用类似的方法在回调中获得结果。这是针对url测试的,url返回一个包含10个用户对象的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();
}
}
public类MainActivity扩展了AppCompatActivity{
私有ArrayList ArrayList;
私自交易;
专用阵列适配器;
私有列表视图列表视图;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
trans=新trans();
arrayList=新的arrayList();
适配器=新的ArrayAdapter(MainActivity.this,android.R.layout.simple\u list\u item\u 1,arrayList);
listView=(listView)findViewById(android.R.id.list);
setAdapter(适配器);
}
@凌驾
受保护的void onResume(){
trans.suggest(MainActivity.this,new AsyncResponse()){
@凌驾
公共void onResponse(字符串响应){
arrayList.clear();//防止重复数据
试一试{
//被测试的URL返回一个JSONArray
//如有必要,更改为JSONObject
JSONArray JSONArray=新JSONArray(响应);
for(int i=0;i
您是否真的收到了服务器的响应?因为你的trans.suggest
函数正在返回null
是的,我确定,我用邮递员测试了它,并在日志中打印了我的响应一切都很好@ChrisStillwellOh等等,我看到问题了。。。您在请求完成之前返回了对象[0]。您不应该返回对象,而应该在onResponse
中进行回调,并以这种方式传递值。哦,您是对的,但怎么做呢?请在回答中发布,这样我就可以接受@ChrisStillwellVolley是异步的,这意味着返回对象[0]代码>很可能在对象[0]=响应之前执行谢谢你解决了我遇到的最大问题之一。是的,我需要上下文,因为我从资产中的配置文件获取url和端口。但另一个问题是:是否可以将来自不同Trans函数的多个请求发送到服务器并获得每个函数的响应?您一次只能接受一个响应,但可以运行多个Trans.suggest
(或任何您想调用的)方法。只需将异步响应传递给volley,并将onResponse
的主体替换为您想做的任何事情。我是说,同时使用不同的函数,如Trans.suggest和Trans.login?有可能吗?是的,例如,在点击按钮的地方放置一个Trans.login
,应该可以正常工作。不太确定你在问什么我在问从不同函数(例如Trans.suggest和Trans.login)调用多个connect()方法不会有任何问题吗?例如错误的数据返回或“强制关闭”?
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);
}
}
public class Trans extends Server {
public void suggest(Context context, AsyncResponse<String> asyncResponse) {
connect("xxxxxxxx", Request.Method.GET, asyncResponse);
}
}
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();
}
}