我们正在服务器上进行大量(所有必要的)调用来获取用户数据,为此我们创建了一个公共(public)类来发布数据,并以 JSON 对象的形式检索响应。但是这样我们的应用程序变得太慢了,所以我们在想,我们可以通过异步任务检索数据。
因此我们修改了代码,如下所示:-
UserFunction.java
public JSONObject getUserData(String userName,String pNumber){
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", getUser));
params.add(new BasicNameValuePair("search_number_array", userName));
params.add(new BasicNameValuePair("pNumber", pNumber));
params.add(new BasicNameValuePair("id", pNumber));
// getting JSON Object
JSONParser jsonParser1=new JSONParser(loginURL, params);
// jsonParser1.getJSONFromUrl(loginURL, params);
jsonParser1.execute();
Jsonresult j1=new Jsonresult();
JSONObject json =j1.getjObjResult();
Log.d("Response:", json.toString()); //line 45, on which getting error
return json;
}
JSONParse.java
public class JSONParser extends AsyncTask<String, String, JSONObject> {
static InputStream is = null;
static JSONObject jObj = null;
Jsonresult obj;
static String json = "";
List<NameValuePair> postparams= new ArrayList<NameValuePair>();
String URL=null;
// constructor
public JSONParser(String url, List<NameValuePair> params) {
URL=url;
postparams=params;
Log.e("entered constructor", "entered in constructor ");
// Making HTTP request
}
@Override
protected JSONObject doInBackground(String... strings) {
Log.e("entered in bg", "entered in doinbackground ");
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(URL);
httpPost.setEntity(new UrlEncodedFormEntity(postparams));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
Log.e("JSON", json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
public void getJSONFromUrl(String url, List<NameValuePair> params) {
URL=url;
postparams=params;
Log.e("entered ", "entered in getjsonurl ");
// Making HTTP request
}
@Override
protected void onPostExecute(JSONObject result) {
this.obj.setjObjResult(result);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
}
Jsonresult.java
public class Jsonresult {
JSONObject jObjResult = null;
public JSONObject getjObjResult() {
return jObjResult;
}
public void setjObjResult(JSONObject jObjResult) {
this.jObjResult = jObjResult;
}
}
但是我们收到了这个错误
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.json.JSONObject.toString()' on a null object reference
at com.keepAeye.gps.UserFunctions.getUserData(UserFunctions.java:45)
表示控制在完成后台进程之前进行。 请告诉我们如何解决这个问题?
最佳答案
当你打电话的时候
jsonParser1.execute();
异步任务发生在另一个线程中。这意味着这些行
Jsonresult j1=new Jsonresult();
JSONObject json =j1.getjObjResult();
Log.d("Response:", json.toString());
return json;
get 在 JSONParser 的 doInBackground get 执行之前执行(实际上它们都是并行运行的)。
这意味着当您调用 j1.getjObjResult();
中的代码时
@Override
protected void onPostExecute(JSONObject result) {
this.obj.setjObjResult(result);
}
甚至还没有执行。解决这个问题的简单方法是使用类似的界面。
public interface CallBack {
void onSuccess(JSONObject json);
}
然后在您的 UserFunction 类链接中实现它
class UserFunction implements CallBack {
...
@Override
public void onSuccess(JSONObject json) {
Log.d("Response:", json.toString());
}
}
当您执行 AsyncTask 时,会像这样传递回调的引用
JSONParser jsonParser1=new JSONParser(loginURL, params, this);
并在 AsyncTask 中维护回调的引用,例如
CallBack mCallback;
public JSONParser(String url, List<NameValuePair> params, CallBack callBack) {
URL=url;
postparams=params;
mCallback = callBack;
Log.e("entered constructor", "entered in constructor ");
// Making HTTP request
}
在 AsyncTask 的 onPostExecute 中执行此操作。
@Override
protected void onPostExecute(JSONObject result) {
mCallback.onSuccess(result);
}
关于java - 异步任务android后返回JSON数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40459569/