Volley使用时InterruptedIOException,NoConnectionError

来源:互联网 发布:淘宝假货率 编辑:程序博客网 时间:2024/06/11 04:43

类似问题链接random com.android.volley.NoConnection error, java.io.InterruptedIOException
在项目中使用了Volley,做了一下简单封装,然后犯了个错误。。。
代码如下:

 /**     * @param tag              标识     * @param networkLostTouch 无网络访问时的回调接口     */    public static <T> void addQueue(Request<T> request, String tag, OnNetworkLostTouch networkLostTouch) {        //如果request为空,则不予加入请求队列        if (request == null) {            return;        }        //如果tag标识为空或者空字符串,那么应给予warn,但是仍能继续请求网络        if (StringUtils.isBlank(tag)) {            LogCus.w("此次的网络请求未设置有效的tag,将无法通过cancleRequest取消网络请求");        }        //先检查网络是否可用        if (!NetWorkUtils.isNetworkConnected()) {            networkLostTouch.lostTouch(ResourceUtils.getString(R.string.network_not_avaliable));            return;        }        request.setRetryPolicy(                new DefaultRetryPolicy(                        DEFAULT_TIMEOUT_MS,//默认超时时间                        DefaultRetryPolicy.DEFAULT_MAX_RETRIES,//默认最大尝试次数                        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT                )        );        request.setTag(tag);        mTags.add(tag);        mRequestQueue.add(request);        //我去,妹的纠结了很久的"com.android.volley.NoConnectionError: java.io.InterruptedIOException"原来就是因为增加了这句话//        mRequestQueue.start();    }

错误就是在最后调用了RequestQueue.start()方法,引起的问题“经常会报com.android.volley.NoConnectionError: java.io.InterruptedIOException”,然后就内容加载失败。。。
最后在stackoverflow中找到Michael Cheng的答案,就是应该去掉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 will call stop to “make sure any currently running dispatchers are stopped”,in stop method volley does this below:

public void stop() {    if (mCacheDispatcher != null) {        mCacheDispatcher.quit();    }    for (int i = 0; i < mDispatchers.length; i++) {        if (mDispatchers[i] != null) {            mDispatchers[i].quit();        }    }}

and the quit method does this below:

 public void quit() {    mQuit = true;    interrupt();}

maybe you can see the reason,why interrupted.
More, interrupt method does this below:

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();        }    }}

the reason maybe this as metioned above:

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.

也可以直接在stackoverflow中查看我写的答案,我的名字是xiaoyee

1 0
原创粉丝点击