【问题标题】:How to assign return value of inner class to outer variable如何将内部类的返回值分配给外部变量
【发布时间】:2018-09-30 23:20:29
【问题描述】:

我是 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 的问题。

谁能帮我解决这个问题。无论从内部类返回什么,我都希望在它之外使用这些值。

请帮忙。

【问题讨论】:

  • 该代码应该可以将 strTopics 设置为另一个值,您收到的响应是否可能为空? (所以它将 strTopics 分配给 null)

标签: java retrofit2 anonymous-class


【解决方案1】:

如果您想在通话之外显示结果,则必须等待通话完成。在改造中,call.enqueue 是一个异步任务,这意味着它在不同的线程上执行,可能需要一些时间才能得到结果。

在这里,您的第二个循环,在入队之外,实际上是在调用完成之前执行的。这就是为什么当您尝试访问它时它仍然为空。

要恢复,实际上是按这个顺序执行的:

  • 首先使用Call&lt;List&lt;String&gt;&gt; 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");
      }
});

【讨论】:

    猜你喜欢
    • 2022-11-27
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 2018-03-13
    相关资源
    最近更新 更多