Return 来自 OkHttpClient 异步请求的值

Return value from OkHttpClient async request

在我的第一个 android 项目中,我创建了一个 onClick 事件来调用函数:

public void doSomething(View v) {
        String result = authenticate();
        [...]
}

此函数调用方法:

private String authenticate() {
        OkHttpClient client = new OkHttpClient();

        [...]

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                [...]
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    String responseString = response.body().string();

                    try {
                        JSONObject responseObject = new JSONObject(responseString);
                        String responseObjectAccessToken = responseObject.getString("accesstoken");
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

现在我想 return responseObjectAccessToken 到我的 doSomething 函数。详细的解释会很好,因为我是 Java 和 Android Studio 的新手。

一个建议是通过作为参数传递给您的 authenticate 方法的回调来处理异步响应。在这里,我为那个方法接口使用 Java 8 lambda。

public class MyActivity extends Activity {
  public interface AuthCallback {
    void onAuthResult(String token);
  }

  private String authenticate(AuthCallback callback) {
    // ...
    String responseObjectAccessToken = responseObject.getString("accesstoken");
    callback.onAuthResult(responseObjectAccessToken)
    // ...
  }

  public void doSomething(View v) {
    authenticate((token) -> {
      // do something with token
    });
  }

  // ...

}

如您所见,如果您愿意,可以存储回调:

// ...
AuthCallback cb = new AuthCallback() {
  @Override
  public void onAuthResult(String token) {
    // do something in the view/fragment/activity
  }
}

// then pass it as argument

或者您的 class 可以实现此接口并将其自身传递到方法中:

public class MyActivity extends Activity implements AuthCallback {
  @Override
  public void onAuthResult(String token) {
    // do something
  }

  // ...

  public void doSomething(View v) {
    authenticate(MyActivity.this); // <-- pass itself
  }
}

这里的一个要点是网络发生在一个单独的线程上,所以如果你想在 API 响应后进行一些 UI 更改,你可以使用辅助方法 runOnUiThread在主 ui 线程上进行更改:

authenticate((token) -> {
  runOnUiThread(() -> {
    // do something with UI here
  })
});