Android Retrofit 2等待多个请求

时间:2017-10-17 23:03:57

标签: android asynchronous retrofit2

我正在构建一个活动,我正在从api加载对象列表。我需要使用retrofit发出多个请求,返回不同的对象。我可以提出请求,但我不知道如何检查他们什么时候完成。

以下代码就是我所拥有的。

ApiRepository

public interface ApiRepository {
    @GET("/api/troopmarker.json")
    Call<List<TroopMarker>> getTroopMarkers();

    @GET("/api/troop.json")
    Call<List<Troop>> getTroops();

    @GET("/api/treasure.json")
    Call<List<TroopMarker>> getTreasures();
}

RepositoryService

public interface RepositoryService 
{
    void loadTroops(final TroopCallback callback);
    void loadTroopMarkers(final TroopMarkerCallback callback);
    //void loadTreasures(final TreasureCallback callback);
}

RepositoryServiceImpl

public class RepositoryServiceImpl implements RepositoryService {
    private String url;
    private Activity context;

    public RepositoryServiceImpl(String url, Activity context) {
        this.url = url;
        this.context = context;
    }

    public void loadTroops(final TroopCallback callback) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        ApiRepository repository = retrofit.create(ApiRepository.class);

        repository.getTroops().enqueue(new Callback<List<Troop>>() {
            public List<Troop> troops;

            @Override
            public void onResponse(Call<List<Troop>> call, Response<List<Troop>> response) {
                if(response.isSuccessful()) {
                    Log.d("RETROFIT", "RESPONSE " + response.body().size());
                    callback.onSuccess(response.body());
                }
            }

            @Override
            public void onFailure(Call<List<Troop>> call, Throwable t) {
                CharSequence text = "Error loading troops.";
                int duration = Toast.LENGTH_LONG;

                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
                callback.onSuccess(null);
            }
        });
    }

    public void loadTroopMarkers(final TroopMarkerCallback callback) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        ApiRepository repository = retrofit.create(ApiRepository.class);

        repository.getTroopMarkers().enqueue(new Callback<List<TroopMarker>>() {
            @Override
            public void onResponse(Call<List<TroopMarker>> call, Response<List<TroopMarker>> response) {
                if(response.isSuccessful()) {
                    Log.d("RETROFIT", "RESPONSE " + response.body().size());
                    callback.onSuccess(response.body());
                }
            }

            @Override
            public void onFailure(Call<List<TroopMarker>> call, Throwable t) {
                CharSequence text = "Error loading troops.";
                int duration = Toast.LENGTH_LONG;
                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
                callback.onSuccess(null);
            }
        });
    }

    public void loadTreasures() {

    }
}

LoadActivity

public class LoadActivity extends AppCompatActivity 
{
    //TODO LOAD TROOPS AND TROOPMARKERS
    //Load troops, troopmarkers, treasures and put on map
    public List<Troop> troops;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loading);

        //Start RepositoryService
        final RepositoryService repositoryService = new RepositoryServiceImpl("http://internco.eu", this);

        //Load troops
        repositoryService.loadTroops(new TroopCallback() {
            @Override
            public void onSuccess(List<Troop> troops) {
                Log.d("RETROFIT", "SUCCESFULLY LOADED TROOPS SIZE: " + troops.size());
            }
        });

        //Load troopMarkers
        repositoryService.loadTroopMarkers(new TroopMarkerCallback() {
            public List<TroopMarker> troopMarkers;

            @Override
            public void onSuccess(List<TroopMarker> troopMarkers) {
                Log.d("RETROFIT", "SUCCESFULLY LOADED TROOPMARKERS SIZE: " + troopMarkers.size());
            }
        });

        //Should now here when I'm done with my requests.
        Log.d("RETROFIT", "DONE");
    }
}

有人可以指出我吗?我认为我必须使用RxJava库,但我无法解决这个问题。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

1 hacky这样做的方法是保留2个标志变量 loadTroopsflag &amp; loadTroopMarkersflag 。然后在每次检查的 onSuccess 回调中是否两者都为真,如果是,那么您的请求都已完成。实现这样的解决方法可能存在边缘情况,但它通常应该有效。如果您的请求彼此依赖,那么您将需要使用嵌套的名为ie,

    repositoryService.loadTroops(new TroopCallback() {
        @Override
        public void onSuccess(List<Troop> troops) {
            Log.d("RETROFIT", "SUCCESFULLY LOADED TROOPS SIZE: " + troops.size());

            repositoryService.loadTroopMarkers(new TroopMarkerCallback() {
            public List<TroopMarker> troopMarkers;

            @Override
            public void onSuccess(List<TroopMarker> troopMarkers) {
                Log.d("RETROFIT", "SUCCESFULLY LOADED TROOPMARKERS SIZE: " + troopMarkers.size());
            }
         });
        }
    });

这样的东西,所以如果你有更多的依赖关系,那么你的嵌套回调就会增加,这就是Rxjava会进来并用几行代码解决它。我不认为你需要跳进Rx然而,这是一个相对较小的问题,你Rx java会带来额外的空间,这会增加应用程序的大小以及开发时间。

另请注意您提及的部分

 //Should now here when I'm done with my requests.
    Log.d("RETROFIT", "DONE");

并不意味着请求已完成,它只是意味着它们已排队并正在进行中。这些是异步请求,将在回调完成时完成。