使用Volley发起请求后触发'Explicit termination method close'崩溃求助
从你提供的StrictMode异常栈可以看出,问题的核心是网络Socket资源被创建后没有显式关闭,如果你的StrictMode配置了penaltyDeath策略,就会直接触发应用崩溃。
问题根源分析
异常追踪最终指向Volley的HurlStack.executeRequest方法,说明Volley在依赖OkHttp的HttpURLConnection处理请求时,没有确保所有关联的流/连接资源被正确回收——尤其是在请求失败、或者响应流未被完全读取的场景下,遗漏了close()或disconnect()操作。早期版本的Volley确实存在这类资源泄漏的bug。
解决方案
1. 优先升级Volley到最新稳定版
Google已经在后续Volley版本中修复了这类资源泄漏问题,这是最直接高效的解决方式。更新你的依赖配置:
// 在app模块的build.gradle中 implementation 'com.android.volley:volley:1.2.1' // 可使用更高的稳定版本
升级后,Volley底层会自动处理资源的关闭逻辑,无需修改业务代码。
2. 自定义HurlStack手动确保资源关闭(无法升级Volley时使用)
如果因为项目限制无法升级Volley,可以自定义HurlStack,重写executeRequest方法,在finally块中强制关闭连接和流:
public class SafeHurlStack extends HurlStack { @Override protected HttpResponse executeRequest(HttpURLConnection connection, Map<String, String> additionalHeaders) throws IOException { HttpResponse response = null; try { response = super.executeRequest(connection, additionalHeaders); return response; } finally { // 关闭输入流(包含正常响应流和错误流) InputStream inputStream = null; try { inputStream = connection.getInputStream(); } catch (IOException e) { inputStream = connection.getErrorStream(); } if (inputStream != null) { try { inputStream.close(); } catch (IOException ignored) {} } // 断开连接 connection.disconnect(); } } }
然后在初始化Volley的RequestQueue时替换为这个自定义Stack:
// 替换原有RequestQueue初始化逻辑 RequestQueue queue = Volley.newRequestQueue(context, new SafeHurlStack()); AppController.getInstance().setRequestQueue(queue); // 对应你代码中的AppController
3. 临时调整StrictMode策略(仅用于调试,不推荐生产环境)
如果只是想临时规避崩溃以便调试,可以修改StrictMode配置,取消崩溃惩罚改为仅记录日志:
// 在Application的onCreate方法中添加 StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedClosableObjects() .penaltyLog() // 仅记录日志,不触发崩溃 // .penaltyDeath() 注释掉这一行 .build());
注意:这只是掩盖问题,无法解决资源泄漏的本质,不建议在生产环境使用。
你的代码小优化点
看了你的StringRequest实现,getBody方法中调用this.getParams()是多余的——getParams用于处理GET请求的URL参数,而你已经通过serviceRequest处理了POST请求体,这个调用不会产生实际效果,可以删除以减少不必要的方法执行。
内容的提问来源于stack exchange,提问作者Abhilash

