VolleyエラーNo Connection

7278 ワード

参照先:https://stackoverflow.com/questions/31158858/random-com-android-volley-noconnection-error-java-io-interruptedioexception-st/31181611#31181611
volleyパッケージの方法は次のとおりです.
public  void RequestPost(Context context, String url,String uri, String tag, final Map<String, String> params, VolleyListenerInterface volleyListenerInterface) {
        //         tag    
        SZSIApp.getRequestQueue().cancelAll(tag);
        //        
        HTTPSTrustManager.allowAllSSL();
        //      POST  ,        Map 
        stringRequest = new Utf8StringRequest(Request.Method.POST, url+uri, volleyListenerInterface.responseListener(), volleyListenerInterface.errorListener()){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                return params;
            }
        };
        //          
        stringRequest.setTag(tag);
        //              
        SZSIApp.getRequestQueue().add(stringRequest);
        //         
        SZSIApp.getRequestQueue().start();
    }

ソース分析では、なぜこのメソッドが呼び出された後にInterruptedIOExceptionが頻繁に発生するのかを分析します.実際にvolleyはRequestQueueを初期化する際にstartメソッドを呼び出しました.コードは次のとおりです.
public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
    File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

    String userAgent = "volley/0";
    try {
        String packageName = context.getPackageName();
        PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
        userAgent = packageName + "/" + info.versionCode;
    } catch (NameNotFoundException e) {
    }

    if (stack == null) {
        if (Build.VERSION.SDK_INT >= 9) {
            stack = new HurlStack();
        } else {
            // Prior to Gingerbread, HttpUrlConnection was unreliable.
            // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
            stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
        }
    }

    Network network = new BasicNetwork(stack);

    RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
    queue.start();

    return queue;
}

startメソッドを呼び出すとvolleyはstopメソッドを呼び出し、現在実行中のすべてのdispatcher(配布)が停止していることを確認します.
public void stop() {
    if (mCacheDispatcher != null) {
        mCacheDispatcher.quit();
    }
    for (int i = 0; i < mDispatchers.length; i++) {
        if (mDispatchers[i] != null) {
            mDispatchers[i].quit();
        }
    }
}

dispatcherを停止するとquitメソッドが呼び出されます
 public void quit() {
    mQuit = true;
    interrupt();
}

interruptメソッドには、同期が含まれています.
public void interrupt() {
    // Interrupt this thread before running actions so that other
    // threads that observe the interrupt as a result of an action
    // will see that this thread is in the interrupted state.
    nativeInterrupt();
    synchronized (interruptActions) {
        for (int i = interruptActions.size() - 1; i >= 0; i--) {
            interruptActions.get(i).run();
        }
    }
}

したがってstartメソッドを繰り返し呼び出すと、ネットワークリクエストが失敗する原因は、スレッドが起動前に中断され、他のスレッドが操作によって中断されたと見なすためです.