如何将内部类的返回值分配给外部变量

时间:2018-09-30 23:20:29

标签: java retrofit2 anonymous-class

我是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循环,并且不会打印任何内容。在第二个for循环中获取 NullPointerException 。不确定这也是Retrofit2的问题。

有人可以帮助我如何克服这个问题。无论从内部类返回什么,我都希望这些值可以在内部使用。

请帮助。

1 个答案:

答案 0 :(得分:0)

如果要在呼叫之外显示结果,则必须等待呼叫完成。在改造中,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");
      }
});