无法从 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().