2016-04-22 3 views
1

Проблема в том, что я не могу получить результат JSON от моего doInBackground. Я знаю, что мне нужен обработчик и работаю с onPostExecute, но я не могу заставить его работать. У меня есть контроллер, ответственный за создание консекции, простирающейся от AsyncTask. Я вызываю этот controller.execute() в основном потоке и он дает мне объект AsyncTask вместо JSON. Это контроллер:не может получить Json от AsyncTask

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(); 
    } 
} 

и это главный класс:

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. Или, если есть другой способ его решения, я открываю для sugestions

ответ

1

Проблема здесь о понимании того, как асинхронный задачи работают. Когда вы вызываете Controller.execute(requestObject), он будет работать в фоновом потоке (вне основного потока), и управление переходит к следующей строке.

И, таким образом, с помощью управления временем достигает JSONObject resultFromAsyncTask= new JSONObject(result);, ваш response является НЕ еще неправдоподобным.

Наряду с этим, я не знаю, как вы в состоянии собрать это:

String result = Controller.execute(requestObject); 

Во всяком случае, я бы порекомендовал вам не использовать AsyncTask и вместо того, чтобы использовать OkHttp «s асинхронный вызов, чтобы сделать сетевые запросы.

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

+0

Я не думаю, что вам нужна деталь «нового обработчика» для запуска по основной теме. Обратный вызов возвращается в нужное место, но если вам нужен обработчик, тогда 'response' должен быть сделан' final' в параметре. –

+0

@ cricket_007, я изменил 'Response' на' final', спасибо, что указали это. Но я не согласен с вашим первым моментом. OkHttp ничего не знает о главном потоке и 'onResponse' [работает в фоновом потоке] (http://stackoverflow.com/a/24248963/2720553). –

+0

Я обычно придерживаюсь Volley, поэтому я могу ошибаться, но я нашел этот [пример кода для асинхронного GET] (https://github.com/square/okhttp/blob/master/samples/guide/src/main/ java/okhttp3/recipes/AsynchronousGet.java) от Square's Github –

1

Метод выполнения() экземпляра AsyncTask не будет возвращаться к вам JSON начать assyncrhonous выполнение. Таким образом, эта строка String result = Controller.execute(requestObject); не будет ждать завершения AsynTask, чтобы вернуть переменную json в переменную result, асинхронность выполняется во втором потоке.

Если вы хотите остановить все и дождаться завершения асинтакты, вы должны вызвать метод get: String result = Controller.execute(requestObject).get();. Но, имейте в виду, что вы заморозите свой интерфейс и это не хорошо! Лучший подход - это запустить AsynTask assynchrously и разобраться с json в методе onPostExecute().

Смежные вопросы