Возвращаемое значение из запроса OkHttpClient asyn c - PullRequest
0 голосов
/ 15 января 2020

В моем первом 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();
                    }
                }
            }
        });
    }

Теперь я хотел бы вернуться responseObjectAccessToken для моей doSomething функции. Подробное объяснение было бы здорово, так как я новичок в Java и Android Studio.

1 Ответ

1 голос
/ 15 января 2020

Одним из предложений является обработка этого асинхронного c ответа посредством обратного вызова, который передается в качестве аргумента вашему authenticate методу. Здесь я использую Java 8 лямбда для этого интерфейса одного метода.

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

или ваш Класс может реализовать этот интерфейс и передать себя в метод:

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 ответит, вы можете использовать вспомогательный метод runOnUiThread для внесения изменений в основной поток пользовательского интерфейса:

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

...