GoogleによるAndroid用の通信処理ライブラリVolleyですが、通信のタイムアウトが2500ミリ秒(2.5秒)と短めに設定してあるため、思わぬところでバグが発生することがあります。
ライブラリのコード
現時点(2014/12/11)での最新コミット(1a39583)より
/** The default socket timeout in milliseconds */
public static final int DEFAULT_TIMEOUT_MS = 2500;
タイムアウト時間を変更する
DefaultRetryPolicyとRequest#setRetryPolicyで変更することができます。
/* タイムアウト 10000ミリ秒(10秒)*/
int custom_timeout_ms = 10000;
DefaultRetryPolicy policy = new DefaultRetryPolicy(custom_timeout_ms,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)
request.setRetryPolicy(policy);
DefaultRetryPolicyって何?
リクエストの再送制御を行うRetryPolicyの実装クラスです。コンストラクタからはタイムアウトを含む以下の3つのパラメータが設定可能です。
パラメータ名 | デフォルト値 | デフォルト名 |
---|---|---|
initialTimeoutMs | 2500 | DEFAULT_TIMEOUT_MS |
maxNumRetries | 1 | DEFAULT_MAX_RETRIES |
backoffMultiplier | 1f | DEFAULT_BACKOFF_MULT |
タイムアウト後の流れ
タイムアウトした後はmaxNumRetriesの回数になるまで再試行します
DEFAULT_MAX_RETRIES=1なので、タイムアウトしても1回だけ再試行します。
(注意:再試行のうち1回でも成功すればResponse.Listener#onResponseが呼ばれます。
ErrorListener#onErrorResponseが呼ばれるのは全ての再試行が失敗した場合のみです)
(余談)タイムアウトに泣かされた話
VolleyでAPIを呼んでいた時に、ひとつのAPIで登録/ログインを行っていた。
登録処理は重い。2.5秒以上掛かる。
もちろんVolleyはタイムアウトする。そして自動的にリトライする。
この間にサーバでは登録処理が完了し、次からはログイン処理になる。
処理時間は2.5秒掛からない。
Volleyは通信を完了する。
通信後のLogCatの[retryCount=0]の数字が増えていたら
再試行が発生してるので注意してみると良いかも。
D/Volley﹕ [1295] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] http://xxx.com/xxx 0x316cf6e5 NORMAL 1> [lifetime=3015], [size=96], [rc=200], [retryCount=0]