随机com.android.volley.NoConnection错误,java.io.InterruptedIOException,statuscode = 0

我有一个原生的Android应用程序使用volley框架从PHP服务器端脚本获取数据。

它在大多数时候运作良好,但我有20%的失败率。

错误说:

com.android.volley.NoConnection,java.io.InterruptedIOException。

我调试我发现statuscode = 0 ,这显然是错误的。

我不知道是什么原因? 因为它工作时间最长所以应该没有明显的错误代码。

仅供参考,服务器端的那些PHP脚本对我的IOS应用程序非常有效。

请允许我在这里发布我的代码:

 retryConnBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { txtOut.append("\n"); txtOut.append("Button with Retry Click"); Log.d("Click", "Button Click"); final String url = "https://www.myserver.com/api/getBalanceInfoTest?token=7ff3317a4f3dc07d0c297a7d16d2049c&t=" + System.currentTimeMillis(); //final String url = "http://192.168.1.23/base/test/"; JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() { @Override public void onResponse(JSONObject response) { txtOut.append("\n"); txtOut.append("Result with Retry:"); txtOut.append(response.toString()); Log.d("Response", response.toString()); VolleyLog.e("Response:", response.toString()); } }, new Response.ErrorListener(){ @Override public void onErrorResponse(VolleyError error) { txtOut.append("\n"); txtOut.append("Error with Retry:"); txtOut.append(error.toString()); Log.d("Error.Response", error.toString()); VolleyLog.e("Error:", error.getMessage()); } }); getRequest.setRetryPolicy(new DefaultRetryPolicy(5000, 5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); queue.add(getRequest); queue.start(); } }); } 

有关更多信息,我的PHP脚本的输出是: {"hsaBalance":"1000.00"} ,由PHP Json_encode()函数创建。

我已修复此错误。 这不是网络问题。

 queue.add(getRequest); queue.start(); 

应该

 queue.add(getRequest); 

所以关键是我们应该删除queue.start()

Michael Cheng是对的,因为当我们调用newRequestQueue时,凌空已启动RequestQueue,如下所示:

 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来“确保当前正在运行的调度程序已停止”,在stop方法中,volley执行以下操作:

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

并且退出方法执行以下操作:

  public void quit() { mQuit = true; 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(); } } } 

原因可能如上所述:

在运行操作之前中断此线程,以便其他通过操作观察中断的线程将看到此线程处于中断状态。

您有时遇到连接问题。 查看InterruptedIOException API:

InterruptedIOException指示I / O操作已中断。 抛出InterruptedIOException以指示输入或输出传输已终止,因为执行它的线程已中断。

因此,只有你能做的就是捕获转换JSon时可能出现的exception,并为此提供解决方法。

 // rest of your code... final String url = "https://www.myserver.com/api/getBalanceInfoTest?token=7ff3317a4f3dc07d0c297a7d16d2049c&t=" + System.currentTimeMillis(); try { JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, url, null, // rest of your code... queue.add(getRequest); queue.start(); } catch (InterruptedIOException e) { // do something when fail print error, show a toast System.out.err("Error, connection interrupted" + e.getMessage()); Toast.makeText(getApplicationContext(), "press button again", Toast.LENGTH_LONG).show(); }