(Android | Java) AndroidAsyncHttp (Loopj) для завершения веб-запроса перед продолжением потока

В настоящее время я запрашиваю JsonObject через веб-запрос AsyncHttpClient (loopj), однако запрос довольно медленный, и мне нужен объект для продолжения. В настоящее время программа аварийно завершает работу, поскольку сохраняемый объект пуст, а функция сохранения вызывается до завершения веб-запроса.

Вот фрагмент моего кода того, что я пытаюсь сделать:

   btnCreate.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {


            AsyncHttpClient client = new AsyncHttpClient();
            String apiAddress = MYAPIADDRESS;

            client.get(apiAddress,
                    new JsonHttpResponseHandler() {

                        //@Override
                        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {

                            try {

                                JSONObject tempTransition = response.getJSONArray("items").getJSONObject(0).getJSONObject("snippet");

                                Toast.makeText(getApplicationContext(), tempTransition.get("description").toString(), Toast.LENGTH_SHORT).show();

                                if(!dirDirectoryJson.contains(tempTransition)){
                                    dirDirectoryJson.add(tempTransition);
                                }

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onSuccess(int statusCode, Header[] headers, JSONArray timeline) {

                        }

                        @Override
                        public void onFinish() {
                            // Completed the request (either success or failure)

                        }

                    });

                //*** Crashes here ****
                //dirDirectoryJson returning null object from above due to call before complete web request and crashes the program
                try {

                    getDescription = dirDirectoryJson.get(0).getString("description").toString().trim();
                    setDescription( getDescription ); 

               } catch (JSONException e) {
                    e.printStackTrace();
            }
     }

Я пробовал SyncHttpClient, заставлял поток спать и т. д., а также видел/пробовал эти (и многие другие) ссылки,

Как дождаться окончания асинхронного http, прежде чем продолжить?< /а>

https://forum.qt.io/topic/5389/how-to-ensure-full-asynchronous-web-requests

Как дождаться завершения всех запросов

Как заставить основной поток ждать, когда я не знаю, когда асинхронная задача завершит работу?

Я также попытался поджарить полученный объект, комментируя сохраняющую часть кода. (прокомментировано выше) Код не дал сбой, но тост появляется только через некоторое время, когда веб-запрос завершен.

Как мне решить эту проблему? (т. е. успешно сохранить объект без сбоя приложения только после завершения веб-запроса). Я очень долго искал в Интернете, но не смог найти работающий метод, и я новичок в Android.

Пожалуйста, помогите и дайте мне знать, если потребуется дополнительная информация. Заранее спасибо!


person Candiie    schedule 14.05.2016    source источник
comment
какая функция сохранения?   -  person Shubhank    schedule 14.05.2016
comment
@Shubhank Привет! На самом деле я прокомментировал код выше, в последней попытке поймать. он вылетает при сохранении, даже не дойдя до сохранения :'( я сделал правку, извините за опечатку.   -  person Candiie    schedule 14.05.2016
comment
пожалуйста, переместите этот код также в случае успеха   -  person Shubhank    schedule 14.05.2016
comment
@Shubhank Привет, я пробовал, там написано, что мои переменные, getDescription и setDescription должны быть объявлены окончательными, но я не могу объявить их окончательными.   -  person Candiie    schedule 14.05.2016
comment
объявите их как instance var, затем @Candiie   -  person Shubhank    schedule 14.05.2016
comment
@Шубханк омгош! Огромное спасибо!!! Это было так глупо с моей стороны! Не могу поверить, что я потратил столько часов, пытаясь заставить это работать!!! >< Огромное спасибо! Как сделать ваш ответ правильным? так как вы разместили это как комментарий.   -  person Candiie    schedule 14.05.2016
comment
нет проблем. напишу как ответ :)   -  person Shubhank    schedule 14.05.2016


Ответы (2)


Поскольку выполняемый вами запрос является асинхронным, вы должны выполнить логику использования ответа на запрос в его обработчике завершения.

Измените свой код на что-то вроде

public void onSuccess(int statusCode, Header[] headers, JSONObject response) {

 try {

     JSONObject tempTransition = response.getJSONArray("items").getJSONObject(0).getJSONObject("snippet");

     Toast.makeText(getApplicationContext(), tempTransition.get("description").toString(), Toast.LENGTH_SHORT).show();

     if(!dirDirectoryJson.contains(tempTransition)){
           dirDirectoryJson.add(tempTransition);
     }

     getDescription = dirDirectoryJson.get(0).getString("description").toString().trim();
                setDescription( getDescription );
   } catch (JSONException e) {
      e.printStackTrace();
   }
}

Также сделайте свои переменные как экземпляр var (то есть объявите их в области класса), если показывает, что не может получить доступ к не окончательным переменным в обработчике.

person Shubhank    schedule 14.05.2016

Поскольку асинхронные вызовы выполняются в фоновом режиме, ваш оставшийся код выполняется до фактического сохранения данных.

getDescription=dirDirectoryJson.get(0).getString("description").toString().trim();
                setDescription( getDescription );

напишите эти строки в свой метод onSuccess, чтобы он заработал.

person Pro Mode    schedule 14.05.2016
comment
Привет, я пробовал, он говорит, что мои переменные, getDescription и setDescription должны быть объявлены окончательными, но я не могу объявить их окончательными, так как мне нужно отредактировать данные. - person Candiie; 14.05.2016
comment
затем поместите этот код в другой пользовательский метод и вызовите этот метод в методе onSuccess. - person Pro Mode; 14.05.2016
comment
Привет, у меня уже работает! Из ответа @shubhank я думаю, что ваш метод тоже сработает, но, поскольку он ответил первым, мне придется установить его как ответ. Тем не менее огромное вам спасибо! - person Candiie; 14.05.2016