2016-12-09 2 views
0

Я пытаюсь использовать залп для создания асинхронных параллельных запросов. Я знаю, что это должно быть поведение по умолчанию, я не могу понять, что я делаю неправильно.Volley - почему запросы не выполняются асинхронно?

Я написал контрольно-измерительный тест, чтобы проверить асинхронность обработки RequestQueue. Это должно идти в де androidTest папку, она ничего не утверждаю, я только использую это, чтобы проверить печать() Выход:

package com.test.testparallelvolley; 

import android.content.Context; 
import android.support.test.InstrumentationRegistry; 
import android.support.test.runner.AndroidJUnit4; 

import com.android.volley.AuthFailureError; 
import com.android.volley.NetworkResponse; 
import com.android.volley.Request; 
import com.android.volley.RequestQueue; 
import com.android.volley.Response; 
import com.android.volley.VolleyError; 
import com.android.volley.toolbox.HttpHeaderParser; 
import com.android.volley.toolbox.JsonRequest; 
import com.android.volley.toolbox.Volley; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.junit.BeforeClass; 
import org.junit.Test; 
import org.junit.runner.RunWith; 

import java.io.UnsupportedEncodingException; 
import java.util.ArrayList; 

@RunWith(AndroidJUnit4.class) 
public class ParallelRequestTest { 

    private static Context context; 

    private static RequestQueue mRequestQueue; 

    public ParallelRequestTest(){ 

    } 

    @BeforeClass 
    public static void initilize(){ 
     System.out.println("INITIALIZING"); 

     try { 
      context = InstrumentationRegistry.getTargetContext(); 

      mRequestQueue = newRequestQueue(context.getApplicationContext()); 
     }catch(Throwable t){ 
      t.printStackTrace(); 
     } 
    } 

    @Test 
    public void testAsync() throws Exception{ 

     addRequest("A"); 
     addRequest("B"); 

     Thread.sleep(15000); 

     for(String msg : log){ 
      System.out.println(msg); 
     } 
    } 

    private void addRequest(final String desc) throws AuthFailureError { 
     String url = "https://api.github.com/users/rails/repos"; 
     String body = ""; 

     Response.Listener<JSONArray> success = new Response.Listener<JSONArray>() { 
      @Override 
      public void onResponse(JSONArray response) { 
       log(desc + " success "); 
//    log(response.toString()); 

       if(desc.equals("A")){ 
        try { 
         log(desc + " sleeping 10s "); 
         Thread.sleep(10000); 
         log(desc + " awake "); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
       log(desc + " finish success listener "); 
      } 
     }; 

     Response.ErrorListener error = new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       log(desc + " ERROR " + error.getMessage()); 
       error.printStackTrace(); 
       log(desc + " finish failure listener "); 
      } 
     }; 

     JsonRequest<JSONArray> req = new JsonRequest<JSONArray>(Request.Method.GET, url , body, success, error) { 

      @Override 
      protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) { 
       log(desc + " RESPONSE: " + response.statusCode); 
       try { 
        String jsonString = new String(response.data, 
          HttpHeaderParser.parseCharset(response.headers)); 

        return Response.success(new JSONArray(jsonString), 
          HttpHeaderParser.parseCacheHeaders(response)); 

       } catch (UnsupportedEncodingException e) { 
        e.printStackTrace(); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 

       return null; 
      } 

     }; 

     mRequestQueue.add(req); 

     log("ADDED " + desc); 
    } 

    public static RequestQueue newRequestQueue(Context context) { 
     return Volley.newRequestQueue(context); 
    } 

// public static RequestQueue newRequestQueue(Context context) { 
//  File cacheDir = new File(context.getCacheDir(), "volley"); 
// 
//  HttpStack stack = new HurlStack(); 
// 
//  ByteArrayPool pool = new ByteArrayPool(65536); 
// 
//  Network network = new BasicNetwork(stack, pool){ 
//   @Override 
//   public NetworkResponse performRequest(Request<?> request) throws VolleyError { 
//    log("PERFORMING REQUEST"); 
//    return super.performRequest(request); 
//   } 
//  }; 
// 
//  RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network, 100); 
//  queue.start(); 
// 
//  return queue; 
// } 


    private static ArrayList<String> log = new ArrayList<>(); 

    private static void log(String message){ 
     log.add(message); 
    } 
} 

Я попытался запустить его на эмуляторе, а также на условиях Фактический смартфон, результат тот же. Метод testAsync() выводит следующий результат:

ADDED A 
ADDED B 
PERFORMING REQUEST 
A RESPONSE: 304 
A success 
{"status":"ok"} 
A sleeping 10s 
A awake 
A finish success listener 
PERFORMING REQUEST 
B RESPONSE: 304 
B success 
{"status":"ok"} 
B finish success listener 

Как вы можете видеть, запросы выполняются синхронно. Даже более странный залп ожидает ответа слушателя ответа перед выполнением второго запроса. Я также попытался явно указать размер пула сети и количество рабочих потоков - проверить запрошенную функцию newRequestQueue().

Это файл build.gradle

apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 23 
    buildToolsVersion "23.0.3" 

    defaultConfig { 
     applicationId "com.test.testparallelvolley" 
     minSdkVersion 15 
     targetSdkVersion 23 
     versionCode 1 
     versionName "1.0" 

     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    testCompile 'junit:junit:4.12' 
    compile 'com.android.support:appcompat-v7:23.1.1' 

    compile "com.android.volley:volley:1.0.0" 

    androidTestCompile 'com.android.support:support-annotations:23.1.1' 
    androidTestCompile 'com.android.support.test:rules:0.5' 
    androidTestCompile 'com.android.support.test:runner:0.5' 

} 

и AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.test.testparallelvolley"> 

    <uses-permission android:name="android.permission.INTERNET" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 

    </application> 

</manifest> 

Что я делаю неправильно?

+0

Это запрос * очередь *. Встраивает запросы и оттягивает их, как только может. –

+0

Что вы подразумеваете под «как можно»? В то время как запрос А спал, не должен требовать, чтобы Б был выполнен? – Gus

+0

Я имею в виду, вы не хотели бы насыщать сетевой адаптер, не так ли? Я не утверждаю, что знаю внутренности Volley, но я не уверен, что он использует пул потоков для выполнения запросов по умолчанию по умолчанию. –

ответ

0

Volley RequestQueue работает на основном потоке. Response listener `onError и onSuccess запускаются также в основном потоке. Когда вы спите свой основной поток в A onSuccess Volley не возобновляет свою очередь

Смежные вопросы