web-dev-qa-db-ja.com

「IllegalStateException:すでに実行されました」の改造

IDが5秒ごとに実行されるRetrofitネットワークコールがあります。私の現在のコード:

Handler h = new Handler();
int delay = 5000; //milliseconds

h.postDelayed(new Runnable() {
    public void run() {
        call.enqueue(new Callback<ApiResponse>() {
            @Override
            public void onResponse(Response<ApiResponse> response) {
                Log.d("api", "response: " + response.body().getPosition().getLatitude().toString());
            }

            @Override
            public void onFailure(Throwable t) {

            }
        });
        h.postDelayed(this, delay);
    }
}, delay);

これは1回実行されますが、次に以下をスローします。

Java.lang.IllegalStateException:すでに実行されています。 at retrofit2.OkHttpCall.enqueue(OkHttpCall.Java:52)at retrofit2.ExecutorCallAdapterFactory $ ExecutorCallbackCall.enqueue(ExecutorCallAdapterFactory.Java:57)at orbyt.project.MyFragment $ 1.run(MyFragment.Java:93)

ここで問題は何ですか?

おまけとして、これを処理するためのより良い方法は何ですか?更新ごとに地図を更新します。私はRxを使用しようと考えていましたが、これが適切なユースケースであるかどうか、またはそれを実装する方法はわかりません。

28
Orbit

Callは1回しか使用できません。 そのドキュメント は、1つを複数回使用する方法を示しています。

clone()を使用して、同じパラメーターで同じWebサーバーに複数の呼び出しを行います。これは、ポーリングの実装または失敗した呼び出しの再試行に使用できます。

したがって、call.clone().enqueue(..) for Asynchornousおよびcall.clone().execute() for Synchornousをそれぞれ使用してリクエストごとに、未実行のCallがあることを確認します。

62
Jake Wharton