Как присвоить возвращаемое значение внутреннего класса внешней переменной - PullRequest
0 голосов
/ 01 октября 2018

Я новичок в Java, и я застрял с присвоением возвращаемого значения переменной из анонимного внутреннего класса.

Я хотел получить список строк, которые возвращаются из вызова API.

List<String> **strTopics**=null;
Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(url)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

Call<List<String>> call=retrofit.getSubjects();

call.enqueue(new Callback<List<String>>() {
            @Override
            public void onResponse(Call<List<String>> call, Response<List<String>> response) {
                Log.d("prepareListData","I am success");
                strTopics=response.body();
                for(String str:strTopics)
                 Log.d("Subject Name ",str)
            }

            @Override
            public void onFailure(Call<List<String>> call, Throwable t) {
                Log.d("prepareListData","I am failure");
            }
        });
       //I am having challenges here. After this statement, again "**strTopics**" is becoming null.
      for(String str:strTopics)
                     Log.d("After inner method",str)

Я просто хотел бы упомянуть, если я прокомментирую вышеприведенный цикл for, то только я смогу напечатать имена субъектов, которые находятся внутри метода внутреннего класса.

Если это некомментировано, то нетиз циклов for вызываются и ничего не печатается.Получение NullPointerException во втором цикле for.Не уверен, что это проблема Retrofit2.

Может кто-нибудь помочь мне, как преодолеть эту проблему.Что бы не возвращалось из внутреннего класса, я хочу, чтобы эти значения использовались за его пределами.

Пожалуйста, помогите.

1 Ответ

0 голосов
/ 03 октября 2018

Если вы хотите отобразить результаты за пределами вызова, вам придется подождать, пока вызов не будет завершен.В модифицированной версии call.enqueue - это асинхронная задача, которая означает, что она выполняется в другом потоке, и для получения результата может потребоваться некоторое время.

Здесь ваш второй цикл вне очереди являетсяфактически выполняется до завершения вызова.Вот почему он все еще нулевой, когда вы пытаетесь получить к нему доступ.

Для возобновления он фактически выполняется в следующем порядке:

  • сначала вы создаете свой вызов с помощью Call<List<String>> call=retrofit.getSubjects();
  • затем вы добавляете к нему обратный вызов.Это запускает фоновую задачу, которая будет получать желаемую информацию
  • , пока выполняется фоновая задача, основной поток переходит к следующей инструкции, которая в какой-то момент является вашей второй циклом for
  • .Фоновая задача завершается и вызывает либо метод onResponse, либо метод onFailure, который вы объявили в обратном вызове
  • , затем выполняется код внутри соответствующего метода

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

Если вам нужно использовать результат вашего вызова где-то еще вваш код, я предлагаю вам создать метод, который принимает результат в качестве параметра, и вызвать этот метод в onResponse вашего кода.

void doSomethingWithResult(List<String> result) {
    // do whatever you need with that result
}

// then in your call
call.enqueue(new Callback<List<String>>() {
    @Override
    public void onResponse(Call<List<String>> call, Response<List<String>> response) {
          Log.d("prepareListData","I am success");
          strTopics=response.body();
          for(String str:strTopics)
              Log.d("Subject Name ",str)
          doSomethingWithResult(response.body());
      }

      @Override
      public void onFailure(Call<List<String>> call, Throwable t) {
          Log.d("prepareListData","I am failure");
      }
});
...