Volleyについて調べる(2)
Requestに優先順位を設定する
いつぞやのVolleyについて調べた記事Volleyについて調べる(1) - 未処分利益の続編です。
複数Threadで同時に大量の通信リクエストを実行したり、画面遷移時に前画面の通信リクエストをキャンセルさせないで次画面の通信リクエストを優先したい時などはVolleyのRequestクラスを拡張して、適宜、各リクエストごとに適切なPrioroty(優先順位)を設定します。
優先順位の種別は以下のソースで定義される通りenumの4種類
/** * Priority values. Requests will be processed from higher priorities to * lower priorities, in FIFO order. */ public enum Priority { LOW, NORMAL, HIGH, IMMEDIATE }
文字通りLOWが優先順位が低く、IMMEDIATEが一番高いです。
標準のRequestクラスのデフォルトPriorityはNORMALです。
/** * Returns the {@link Priority} of this request; {@link Priority#NORMAL} by default. */ public Priority getPriority() { return Priority.NORMAL; }
拡張クラスにPriorityのメンバ変数を持ち、セッターメソッドで適切な優先度を設定しゲッターメソッドをオーバーライドします。
(RequestQueue内部でgetPriority()をコールしています)
実際の拡張クラスはこんな感じですかね。
package jp.co.misyobun.app.volleyctrl.request; import com.android.volley.Response.ErrorListener; import com.android.volley.Response.Listener; import com.android.volley.toolbox.StringRequest; public class SampleRequest extends StringRequest { private Priority mPriority = Priority.LOW; /** * コンストラクタ * @param url * @param listener * @param errorListener */ public SampleRequest(String url, Listener<String> listener, ErrorListener errorListener) { super(url, listener, errorListener); } /** * 優先順位を設定する * @param priority 優先順位設定 */ public void setPriority(final Priority priority) { this.mPriority = priority; } /** * 現在の優先順位を返却する * @return 優先順位 */ public Priority getPriority() { return mPriority; } }
上記のSampleRequestを用いて実際に優先度を確認するコードは下記の通りです。
/** * 優先順位を確認する */ private void doExperiment() { final RequestQueue queue = QueueFactory.getInstance(getApplicationContext()); Thread low = new Thread(new Runnable() { @Override public void run() { SampleRequest req1 = new SampleRequest("http://www.yahoo.co.jp", new Listener<String>() { @Override public void onResponse(String response) { Log.i(TAG,"response: req1 LOW"); } }, new ErrorListener() { @Override public void onErrorResponse(VolleyError error) { int errorCode = error.networkResponse.statusCode; Log.i(TAG,"errorCode: " + errorCode); } }); req1.setPriority(Priority.LOW); for (int i = 0; i < 10; i++){ queue.add(req1); } } }); Thread normal = new Thread(new Runnable() { @Override public void run() { SampleRequest req2 = new SampleRequest("http://www.yahoo.co.jp", new Listener<String>() { @Override public void onResponse(String response) { Log.i(TAG,"response: req2 NORMAL"); } }, new ErrorListener() { @Override public void onErrorResponse(VolleyError error) { int errorCode = error.networkResponse.statusCode; Log.i(TAG,"errorCode: " + errorCode); } }); req2.setPriority(Priority.NORMAL); for (int i = 0; i < 10; i++){ queue.add(req2); } } }); Thread high = new Thread(new Runnable() { @Override public void run() { SampleRequest req3 = new SampleRequest("http://www.yahoo.co.jp", new Listener<String>() { @Override public void onResponse(String response) { Log.i(TAG,"response: req3 HIGH"); } }, new ErrorListener() { @Override public void onErrorResponse(VolleyError error) { int errorCode = error.networkResponse.statusCode; Log.i(TAG,"errorCode: " + errorCode); } }); req3.setPriority(Priority.HIGH); for (int i = 0; i < 10; i++){ queue.add(req3); } } }); Thread immediate = new Thread(new Runnable() { @Override public void run() { SampleRequest req4 = new SampleRequest("http://www.yahoo.co.jp", new Listener<String>() { @Override public void onResponse(String response) { Log.i(TAG,"response: req3 IMMEDIATE"); } }, new ErrorListener() { @Override public void onErrorResponse(VolleyError error) { int errorCode = error.networkResponse.statusCode; Log.i(TAG,"errorCode: " + errorCode); } }); req4.setPriority(Priority.IMMEDIATE); for (int i = 0; i < 10; i++){ queue.add(req4); } } }); low.start(); normal.start(); high.start(); immediate.start(); }
上記の処理を実行してみると、下記のログの通り優先順位順にRequestが実行されていました。
01-01 22:33:25.910: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 IMMEDIATE 01-01 22:33:25.920: D/dalvikvm(13067): GC_FOR_ALLOC freed 131K, 4% free 17496K/18068K, paused 15ms, total 15ms 01-01 22:33:25.930: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 IMMEDIATE 01-01 22:33:25.930: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 IMMEDIATE 01-01 22:33:25.930: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 IMMEDIATE 01-01 22:33:25.980: D/dalvikvm(13067): GC_FOR_ALLOC freed 471K, 5% free 17308K/18068K, paused 13ms, total 14ms 01-01 22:33:26.070: D/dalvikvm(13067): GC_FOR_ALLOC freed 505K, 5% free 17315K/18068K, paused 13ms, total 13ms 01-01 22:33:26.140: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 IMMEDIATE 01-01 22:33:26.140: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 IMMEDIATE 01-01 22:33:26.170: D/dalvikvm(13067): GC_FOR_ALLOC freed 509K, 5% free 17317K/18068K, paused 9ms, total 9ms 01-01 22:33:26.230: D/dalvikvm(13067): GC_FOR_ALLOC freed 275K, 4% free 17475K/18068K, paused 10ms, total 10ms 01-01 22:33:26.230: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 IMMEDIATE 01-01 22:33:26.240: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 IMMEDIATE 01-01 22:33:26.290: D/dalvikvm(13067): GC_FOR_ALLOC freed 566K, 5% free 17315K/18068K, paused 10ms, total 10ms 01-01 22:33:26.380: D/dalvikvm(13067): GC_FOR_ALLOC freed 348K, 4% free 17432K/18068K, paused 14ms, total 14ms 01-01 22:33:26.390: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 IMMEDIATE 01-01 22:33:26.390: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 HIGH 01-01 22:33:26.450: D/dalvikvm(13067): GC_FOR_ALLOC freed 408K, 4% free 17381K/18068K, paused 9ms, total 9ms 01-01 22:33:26.460: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 HIGH 01-01 22:33:26.480: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 HIGH 01-01 22:33:26.490: D/dalvikvm(13067): GC_FOR_ALLOC freed 471K, 5% free 17311K/18068K, paused 10ms, total 10ms 01-01 22:33:26.560: D/dalvikvm(13067): GC_FOR_ALLOC freed 497K, 5% free 17324K/18068K, paused 10ms, total 10ms 01-01 22:33:26.580: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 HIGH 01-01 22:33:26.620: D/dalvikvm(13067): GC_FOR_ALLOC freed 379K, 4% free 17403K/18068K, paused 13ms, total 13ms 01-01 22:33:26.630: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 HIGH 01-01 22:33:26.630: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 HIGH 01-01 22:33:26.650: D/dalvikvm(13067): GC_FOR_ALLOC freed 455K, 4% free 17347K/18068K, paused 11ms, total 11ms 01-01 22:33:26.680: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 HIGH 01-01 22:33:26.720: D/dalvikvm(13067): GC_FOR_ALLOC freed 540K, 5% free 17317K/18068K, paused 14ms, total 14ms 01-01 22:33:26.740: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 HIGH 01-01 22:33:26.790: D/dalvikvm(13067): GC_FOR_ALLOC freed 476K, 4% free 17352K/18068K, paused 9ms, total 9ms 01-01 22:33:26.800: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 HIGH 01-01 22:33:26.820: D/dalvikvm(13067): GC_FOR_ALLOC freed 405K, 4% free 17395K/18068K, paused 9ms, total 9ms 01-01 22:33:26.830: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req3 HIGH 01-01 22:33:26.860: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req2 NORMAL 01-01 22:33:26.880: D/dalvikvm(13067): GC_FOR_ALLOC freed 507K, 5% free 17319K/18068K, paused 9ms, total 9ms 01-01 22:33:26.920: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req2 NORMAL 01-01 22:33:26.940: D/dalvikvm(13067): GC_FOR_ALLOC freed 512K, 5% free 17315K/18068K, paused 9ms, total 9ms 01-01 22:33:27.010: D/dalvikvm(13067): GC_FOR_ALLOC freed 352K, 4% free 17445K/18068K, paused 15ms, total 15ms 01-01 22:33:27.020: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req2 NORMAL 01-01 22:33:27.020: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req2 NORMAL 01-01 22:33:27.050: D/dalvikvm(13067): GC_FOR_ALLOC freed 366K, 4% free 17367K/18068K, paused 15ms, total 15ms 01-01 22:33:27.050: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req2 NORMAL 01-01 22:33:27.080: D/dalvikvm(13067): GC_FOR_ALLOC freed 386K, 4% free 17387K/18068K, paused 9ms, total 9ms 01-01 22:33:27.080: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req2 NORMAL 01-01 22:33:27.170: D/dalvikvm(13067): GC_FOR_ALLOC freed 576K, 5% free 17322K/18068K, paused 12ms, total 12ms 01-01 22:33:27.220: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req2 NORMAL 01-01 22:33:27.230: D/dalvikvm(13067): GC_FOR_ALLOC freed 459K, 4% free 17374K/18068K, paused 10ms, total 10ms 01-01 22:33:27.240: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req2 NORMAL 01-01 22:33:27.240: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req2 NORMAL 01-01 22:33:27.300: D/dalvikvm(13067): GC_FOR_ALLOC freed 409K, 5% free 17331K/18068K, paused 12ms, total 12ms 01-01 22:33:27.300: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req2 NORMAL 01-01 22:33:27.350: D/dalvikvm(13067): GC_FOR_ALLOC freed 523K, 5% free 17317K/18068K, paused 13ms, total 13ms 01-01 22:33:27.450: D/dalvikvm(13067): GC_FOR_ALLOC freed 386K, 4% free 17427K/18068K, paused 16ms, total 16ms 01-01 22:33:27.460: D/dalvikvm(13067): GC_FOR_ALLOC freed 86K, 3% free 17550K/18068K, paused 14ms, total 14ms 01-01 22:33:27.480: D/dalvikvm(13067): GC_FOR_ALLOC freed 90K, 4% free 17515K/18068K, paused 10ms, total 10ms 01-01 22:33:27.480: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req1 LOW 01-01 22:33:27.490: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req1 LOW 01-01 22:33:27.490: D/dalvikvm(13067): GC_FOR_ALLOC freed 222K, 4% free 17486K/18068K, paused 8ms, total 8ms 01-01 22:33:27.490: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req1 LOW 01-01 22:33:27.490: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req1 LOW 01-01 22:33:27.550: D/dalvikvm(13067): GC_FOR_ALLOC freed 470K, 5% free 17308K/18068K, paused 8ms, total 8ms 01-01 22:33:27.600: D/dalvikvm(13067): GC_FOR_ALLOC freed 499K, 5% free 17321K/18068K, paused 10ms, total 10ms 01-01 22:33:27.720: D/dalvikvm(13067): GC_FOR_ALLOC freed 346K, 4% free 17479K/18068K, paused 27ms, total 27ms 01-01 22:33:27.740: D/dalvikvm(13067): GC_FOR_ALLOC freed 76K, 3% free 17549K/18068K, paused 23ms, total 23ms 01-01 22:33:27.750: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req1 LOW 01-01 22:33:27.750: D/Volley(13067): [1] Request.finish: 3107 ms: [ ] http://www.yahoo.co.jp 0x7e3fa503 LOW 20 01-01 22:33:27.770: D/dalvikvm(13067): GC_FOR_ALLOC freed 186K, 4% free 17491K/18068K, paused 20ms, total 21ms 01-01 22:33:27.790: D/dalvikvm(13067): GC_FOR_ALLOC freed 53K, 3% free 17550K/18068K, paused 19ms, total 19ms 01-01 22:33:27.790: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req1 LOW 01-01 22:33:27.790: D/Volley(13067): [1] Request.finish: 3153 ms: [ ] http://www.yahoo.co.jp 0x7e3fa503 LOW 20 01-01 22:33:27.790: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req1 LOW 01-01 22:33:27.790: D/Volley(13067): [1] Request.finish: 3155 ms: [ ] http://www.yahoo.co.jp 0x7e3fa503 LOW 20 01-01 22:33:27.810: D/dalvikvm(13067): GC_FOR_ALLOC freed 233K, 4% free 17386K/18068K, paused 16ms, total 16ms 01-01 22:33:27.820: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req1 LOW 01-01 22:33:27.820: D/Volley(13067): [1] Request.finish: 3176 ms: [ ] http://www.yahoo.co.jp 0x7e3fa503 LOW 20 01-01 22:33:28.020: D/dalvikvm(13067): GC_FOR_ALLOC freed 526K, 4% free 17362K/18068K, paused 22ms, total 22ms 01-01 22:33:28.040: D/dalvikvm(13067): GC_FOR_ALLOC freed 162K, 4% free 17470K/18068K, paused 17ms, total 17ms 01-01 22:33:28.040: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req1 LOW 01-01 22:33:28.040: D/Volley(13067): [1] Request.finish: 3401 ms: [ ] http://www.yahoo.co.jp 0x7e3fa503 LOW 20 01-01 22:33:28.040: I/jp.co.naoto0101.app.volleyctrl.MainActivity(13067): response: req1 LOW
結論
ユーザ体験の状況に合わせて、RequestQueue内部に装填されたRequestの実行順番を動的に変えたい場合はPriorityを利用するのがいいでしょう。
(ただし、前提としてRequestクラスを拡張する必要があります)