排球 - 为什么请求不是异步执行的?

时间:2016-12-09 00:09:22

标签: android asynchronous android-volley

我正在尝试使用volley来发出异步并行请求。我知道这应该是默认行为,我无法弄清楚我做错了什么。

我编写了一个Instrumentation测试来检查RequestQueue处理的异步性。这应该在de androidTest 文件夹里面,它不会断言任何东西,我只是用它来检查print()输出:

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>

我做错了什么?

1 个答案:

答案 0 :(得分:0)

Volley RequestQueue正在主线程上运行。响应侦听器的onError和onSuccess也在主线程上运行。当您在A onSuccess中休眠主线程时,Volley不会恢复其队列