类似问题链接random com.android.volley.NoConnection error, java.io.InterruptedIOException
在项目中使用了Volley,做了一下简单封装,然后犯了个错误。。。
代码如下:
/**
* @param tag 标识
* @param networkLostTouch 无网络访问时的回调接口
*/
public static void addQueue(Request 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方法的调用。
实际上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