如何等待异步方法

Abh*_*h K 6 java android retrofit2

我需要返回值uId。我在onResponse()函数内的第一个日志语句中获得了正确的值。但是当涉及到 return 语句时,它返回null

我认为 onResponse() 正在另一个线程上运行。如果是这样,我怎样才能让getNumber()函数等待onResponse()函数完成执行。(如 thread.join())

或者还有其他解决方案吗?

代码 :

String uId;
public String getNumber() {

    ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
    Call<TopLead> call = apiInterface.getTopLead();
    call.enqueue(new Callback<TopLead>() {
        @Override
        public void onResponse(Call<TopLead> call, Response<TopLead> response) {
            String phoneNumber;
            TopLead topLead = response.body();
            if (topLead != null) {
                phoneNumber = topLead.getPhoneNumber().toString();
                uId = topLead.getUId().toString();
                //dispaly the correct value of uId
                Log.i("PHONE NUMBER, UID", phoneNumber +", " + uId);
                onCallCallback.showToast("Calling " + phoneNumber);
            } else {
                onCallCallback.showToast("Could not load phone number");
            }
        }

        @Override
        public void onFailure(Call<TopLead> call, Throwable t) {
            t.printStackTrace();
        }
    });
    //output: Return uid null
    Log.i("Return"," uid" + uId);
    return uId; 
Run Code Online (Sandbox Code Playgroud)

小智 9

您的方法执行异步请求。所以操作“return uId;”不会等到您的请求完成,因为它们在不同的线程上。

我可以建议几种解决方案

  1. 使用接口回调

     public void getNumber(MyCallback callback) {
       ...
        phoneNumber = topLead.getPhoneNumber().toString();
        callback.onDataGot(phoneNumber);
     }
    
    Run Code Online (Sandbox Code Playgroud)

你的回调接口

     public interface MyCallback {

        void onDataGot(String number);
     }
Run Code Online (Sandbox Code Playgroud)

最后,调用方法

getNumber(new MyCallback() {
    @Override
    public void onDataGot(String number) {
    // response
    }
});
Run Code Online (Sandbox Code Playgroud)
  1. 使用Kotlin 时(我认为是时候使用 Kotlin 而不是 Java 了 :))

    fun getNumber(onSuccess: (phone: String) -> Unit) {
      phoneNumber = topLead.getPhoneNumber().toString()
      onSuccess(phoneNumber)
    }
    
    Run Code Online (Sandbox Code Playgroud)

调用方法

    getNumber {
      println("telephone $it")
    }
Run Code Online (Sandbox Code Playgroud)