【问题标题】:Android how to get response string from Callback using OkHttp?Android如何使用OkHttp从回调中获取响应字符串?
【发布时间】:2015-06-30 18:32:02
【问题描述】:

这是我的代码:

    OkHttpClient okHttpClient = new OkHttpClient();

    Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build();

    Callback callback = new Callback() {
        @Override
        public void onFailure(Request request, IOException e) {

        }

        @Override
        public void onResponse(Response response) throws IOException {

        }
    };

    okHttpClient.newCall(request).enqueue(callback);

    String responseString;

在上面的代码中,我想将来自 onResponse() 方法的 response.body().string() 的值存储在变量 responseString 中,但是我无法访问它。

【问题讨论】:

  • 我有点困惑你在这里想要做什么。如果此代码存在于本地函数中,那么使用异步回调并存储在调用函数中声明的变量有什么好处?除非您先阻止,否则无论如何您都无法使用它。您可以将响应存储在类实例变量中,这样可以正常工作。尽管您以错误的方式进行此操作,但很有可能。
  • @MattWolfe 你可能是对的,我是 Android 开发的新手。我想做的是获取一些像link 这样的数据,将其保存在变量中,解析它,然后使用视图将其显示在屏幕上。将数据存储在实例变量中是正确的方法还是有另一种方法?谢谢。
  • 我只想让你的活动/片段实现回调:然后执行:okHttpClient.newCall(request).enqueue(this);然后在你的 onResponse 中解析它,你可以将结果显示到屏幕上。

标签: java android okhttp


【解决方案1】:

我认为你想做的是这样的:

public class MyActivity extends Activity implements Callback , View.OnClickListener {


 @Override
 public void onCreate(Bundle savedState) {
   super.onCreate(savedState);
   findViewById(R.id.DoHttp).setOnClickListener(this);
 } 

 @Override
 public void onClick(View v) {
   if (v.getId(() == R.id.DoHttp) {

     OkHttpClient okHttpClient = new OkHttpClient();

     Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build();
     okHttpClient.newCall(request).enqueue(this);
   }
 }


 @Override
 public void onFailure(Request request, IOException e) {
  //do something to indicate error
 }

  @Override
  public void onResponse(Response response) throws IOException {
    if (response.isSuccessful()) {
     parse(response.body().string());
    }
  }

  private void parse(String response) {
   //do something with response
  } 
}

在上面的活动中,我们实现了回调,然后当我们创建 okhttp 请求时,我们将自己的实例(this)传递给它,这样我们就可以让 oktthp 回调类,我们可以只做一个内部类很容易,但这减少了我们必须制作的类的数量。我使用按钮单击来说明何时进行 Http 调用,但这可能是其他时间,例如它可能发生在第一次创建屏幕时(在 onCreate 中)。小心屏幕旋转。这也假设回调是在主线程上完成的,我认为它会是,但我并不肯定,因为我使用 okttp 的方式与你不同。如果它没有在主线程的响应中返回结果,那么您可以调用 runOnUiThread() 并传递给它一个 Runnable 来完成更新视图的工作。

【讨论】:

  • 您能否发布一个您将使用的示例/链接,因为您所说的上述方法会在每次屏幕旋转时执行网络调用,对吗?
  • 这是一个没有单一或简单解决方案的常见问题。
【解决方案2】:

如果您将responseString 声明移动为实例变量,那么您将能够在CallbackonResponse 方法中为其赋值。

public class MyClass {

    private String responseString; 

    // your class implementation

}

我已经修改了您发布的代码,并在下面进行了必要的更改:

OkHttpClient okHttpClient = new OkHttpClient();

Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build();

Callback callback = new Callback() {
    @Override
    public void onFailure(Request request, IOException e) {

    }

    @Override
    public void onResponse(Response response) throws IOException {
        responseString = response.body().string();
    }
};

okHttpClient.newCall(request).enqueue(callback);

【讨论】:

  • 不幸的是,我无法更改 onResponse 中 responseString 的值,因为它是最终的
  • 您说的完全正确,对错误深表歉意。我已经修改了我的代码,但如果它不再有用,我会删除它。
  • 谢谢。事实证明,代码确实有效,但是更新 responseString 的值需要一段时间。
  • 是的,这是因为它是异步发生的,并且取决于网络的响应时间和您从中接收数据的端点。对于从 Internet 源接收数据的所有应用程序都是如此。
【解决方案3】:

第一个答案很接近,但您不能在方法 onResponse 中分配最终变量。解决方法是输入final String[] responseString = new String[1]; 并分配responseString[0] = response.body().string();

【讨论】:

  • 更改我的代码后,gist.github.com/taimoor-ahmad/ef9515751294d80d460e 我得到 java.lang.NullPointerException: println needs a message when trying to use the value of responseString[0] in my Log
  • 因为onResponse中的代码还没有被回调,所以必须在回调执行后打印出来
猜你喜欢
  • 2018-10-24
  • 2015-12-12
  • 1970-01-01
  • 2018-02-04
  • 2015-03-29
  • 2019-12-20
  • 2020-06-01
  • 1970-01-01
  • 2018-10-12
相关资源
最近更新 更多