Java Android Retrofit中如何传递返回值到方法并获取响应值
问题根因
你遇到的问题本质是Retrofit的enqueue方法是异步执行的:getValue()方法调用call.enqueue()之后不会等待网络请求返回,会直接执行后续的返回语句,这时候onResponse回调还没触发,mValue还没完成赋值,你调用onPass()时拿到的就是空值,自然请求会失败。
另外你原代码存在泛型匹配错误:Call<Value>对应的Callback泛型写成了Callback<Login>,这个错误也会导致请求异常,需要改成Callback<Value>。
解决方案
方案1:在mValue赋值完成后直接调用onPass
保证拿到mValue之后再发起第二个请求,修改后代码如下:
// 不需要返回mValue,直接在回调里触发后续逻辑 public void getValue(){ User user = new User(mEmail,mPassword); Call<Value> call = xyz.value(user); call.enqueue(new Callback<Value>() { @Override public void onResponse(Call<Value> call, Response<Value> response) { if(response.isSuccessful()){ mValue = response.body().getValue(); // 拿到值后直接调用onPass发起请求 onPass(); }else{ Toast.makeText(MainActivity.this,"xyz",Toast.LENGTH_LONG).show(); } } @Override public void onFailure(Call<Value> call, Throwable t) { Toast.makeText(MainActivity.this,"Failed!",Toast.LENGTH_LONG).show(); } }); } private void onPass() { Call<PassData> call1 = xyz.user(mValue); call1.enqueue(new Callback<PassData>() { @Override public void onResponse(Call<PassData> call, Response<PassData> response) { if(response.isSuccessful()){ // 直接读取response.body打印、存储响应数据,根据你PassData的实际属性调整即可 PassData result = response.body(); Log.d("接口响应", result.toString()); }else{ Toast.makeText(getApplicationContext(),"Unauthenticated",Toast.LENGTH_LONG).show(); } } @Override public void onFailure(Call<PassData> call, Throwable t) { Toast.makeText(getApplicationContext(),"Unauthenticated",Toast.LENGTH_LONG).show(); } }); }
方案2:自定义回调接口解耦(可选)
如果getValue需要多处复用,可以自定义回调接口接收返回值,避免逻辑耦合:
- 先定义回调接口
public interface ValueLoadCallback { void onLoadSuccess(String value); void onLoadFail(); }
- 修改getValue方法
public void getValue(ValueLoadCallback callback){ User user = new User(mEmail,mPassword); Call<Value> call = xyz.value(user); call.enqueue(new Callback<Value>() { @Override public void onResponse(Call<Value> call, Response<Value> response) { if(response.isSuccessful()){ mValue = response.body().getValue(); callback.onLoadSuccess(mValue); }else{ Toast.makeText(MainActivity.this,"xyz",Toast.LENGTH_LONG).show(); callback.onLoadFail(); } } @Override public void onFailure(Call<Value> call, Throwable t) { Toast.makeText(MainActivity.this,"Failed!",Toast.LENGTH_LONG).show(); callback.onLoadFail(); } }); }
- 调用示例
getValue(new ValueLoadCallback() { @Override public void onLoadSuccess(String value) { // 拿到值后调用onPass,也可以直接把value作为参数传给onPass onPass(); } @Override public void onLoadFail() { // 自定义失败处理逻辑 } });
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

