无法从 AsyncTask 获取 Json
can't get Json from AsyncTask
问题是我无法从 doInBackground 获得 JSON 结果。我知道我需要一个处理程序并使用 onPostExecute,但我无法让它工作。我有一个控制器负责使连接从 AsyncTask 扩展。我在主线程上调用 controller.execute(),它给了我一个 AsyncTask 对象而不是 JSON。
这是控制器:
final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
@Override
protected String doInBackground(String... params){
try {
JSONObject newJson = new JSONObject(params.toString());
String dirArchivo = "http://10.0.2.2/SoulStoreProject/"+newJson.get("dir");
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, newJson.toString());
Request request = new Request.Builder()
.url(dirArchivo)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (IOException e) {
return e.getMessage().toString();
} catch (JSONException e) {
return e.getMessage().toString();
}
}
这是主要的 class:
JSONObject requestObject = new JSONObject();
requestObject.put("nick", txtNicklog.getText().toString());
requestObject.put("password", txtPasslog.getText().toString());
requestObject.put("dir", "devolverJugador.php");
String result = Controller.execute(requestObject);
JSONObject resultFromAsyncTask= new JSONObject(result);
我不知道在哪里编写处理程序以及如何从 onPostExecute 调用它。或者,如果有另一种方法可以解决它,我愿意接受建议
这里的问题是关于理解异步任务是如何工作的。当您调用 Controller.execute(requestObject)
时,它将 运行 在后台线程(离开主线程)并且控制权将传递到下一行。
因此,当控制到达 JSONObject resultFromAsyncTask= new JSONObject(result);
时,您的 response
NOT 尚未获取。
除此之外,我不知道你是如何编译的:
String result = Controller.execute(requestObject);
无论如何,我建议您不要使用AsyncTask
,而是使用OkHttp
的异步调用来发出网络请求。
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, newJson.toString());
Request request = new Request.Builder()
.url(dirArchivo)
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if(resonse.isSuccessful(){
//Running on UI thread, because response received is NOT on UI thread.
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
//use response to update any UI component
}
});
}
}
});
注意:我假设您使用的是最新版本的 OkHttp
,即 3.2.0
AsyncTask 实例的方法 execute() 不会 return 您 json 启动异步执行。因此,这一行 String result = Controller.execute(requestObject);
不会等到 AsynTask 完成后才 return 到 json 结果变量,异步任务 运行 在第二个线程中。
如果你想停止一切并等待 asynctask 完成,你必须调用方法 get:String result = Controller.execute(requestObject).get();
。但是,请记住,您会冻结 UI,这可不好!最好的方法是 运行 AsynTask 异步处理 json 方法 onPostExecute().
问题是我无法从 doInBackground 获得 JSON 结果。我知道我需要一个处理程序并使用 onPostExecute,但我无法让它工作。我有一个控制器负责使连接从 AsyncTask 扩展。我在主线程上调用 controller.execute(),它给了我一个 AsyncTask 对象而不是 JSON。 这是控制器:
final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
@Override
protected String doInBackground(String... params){
try {
JSONObject newJson = new JSONObject(params.toString());
String dirArchivo = "http://10.0.2.2/SoulStoreProject/"+newJson.get("dir");
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, newJson.toString());
Request request = new Request.Builder()
.url(dirArchivo)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (IOException e) {
return e.getMessage().toString();
} catch (JSONException e) {
return e.getMessage().toString();
}
}
这是主要的 class:
JSONObject requestObject = new JSONObject();
requestObject.put("nick", txtNicklog.getText().toString());
requestObject.put("password", txtPasslog.getText().toString());
requestObject.put("dir", "devolverJugador.php");
String result = Controller.execute(requestObject);
JSONObject resultFromAsyncTask= new JSONObject(result);
我不知道在哪里编写处理程序以及如何从 onPostExecute 调用它。或者,如果有另一种方法可以解决它,我愿意接受建议
这里的问题是关于理解异步任务是如何工作的。当您调用 Controller.execute(requestObject)
时,它将 运行 在后台线程(离开主线程)并且控制权将传递到下一行。
因此,当控制到达 JSONObject resultFromAsyncTask= new JSONObject(result);
时,您的 response
NOT 尚未获取。
除此之外,我不知道你是如何编译的:
String result = Controller.execute(requestObject);
无论如何,我建议您不要使用AsyncTask
,而是使用OkHttp
的异步调用来发出网络请求。
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, newJson.toString());
Request request = new Request.Builder()
.url(dirArchivo)
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if(resonse.isSuccessful(){
//Running on UI thread, because response received is NOT on UI thread.
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
//use response to update any UI component
}
});
}
}
});
注意:我假设您使用的是最新版本的 OkHttp
,即 3.2.0
AsyncTask 实例的方法 execute() 不会 return 您 json 启动异步执行。因此,这一行 String result = Controller.execute(requestObject);
不会等到 AsynTask 完成后才 return 到 json 结果变量,异步任务 运行 在第二个线程中。
如果你想停止一切并等待 asynctask 完成,你必须调用方法 get:String result = Controller.execute(requestObject).get();
。但是,请记住,您会冻结 UI,这可不好!最好的方法是 运行 AsynTask 异步处理 json 方法 onPostExecute().