You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Volley库无法获取API数据,请求协助排查问题

问题排查:Volley请求News API触发「Something went wrong!」错误

尝试通过News API获取新闻数据,但应用启动后总会触发ErrorListener中的Toast提示「Something went wrong!」,无法定位具体问题,相关代码如下:

请求代码

val APIurl = "https://newsapi.org/v2/top-headlines?country=in&apiKey=f2c9d983c1c44dd3a89ab47aacd520cb"

// Request a string response from the provided URL.
val jsonObjectRequest = JsonObjectRequest(
    Request.Method.GET, APIurl, null,
    {
        val jsonObjectArray = it.getJSONArray("articles")
        val newsList = ArrayList<News>()

        for(i in 0 until jsonObjectArray.length()){
            val currJsonObject = jsonObjectArray.getJSONObject(i)
            val news = News(
                currJsonObject.getString("title"),
                currJsonObject.getString("author"),
                currJsonObject.getString("url"),
                currJsonObject.getString("urlToImage")
            )
            newsList.add(news)
        }
        mAdapter.updateList(newsList)
    },
    //While opening the app it is showing this message
    {
        Toast.makeText(this, "Something went wrong!", Toast.LENGTH_SHORT).show()
    })

// Add the request to the RequestQueue.
MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest)

Volley单例类代码

class MySingleton(context: Context) {
    companion object {
        @Volatile
        private var INSTANCE: MySingleton? = null
        fun getInstance(context: Context) =
            INSTANCE ?: synchronized(this) {
                INSTANCE ?: MySingleton(context).also {
                    INSTANCE = it
                }
            }
    }

    val requestQueue: RequestQueue by lazy {
        // applicationContext is key, it keeps you from leaking the
        // Activity or BroadcastReceiver if someone passes one in.
        Volley.newRequestQueue(context.applicationContext)
    }
    fun <T> addToRequestQueue(req: Request<T>) {
        requestQueue.add(req)
    }
}

排查方案

1. 先获取具体错误信息

当前错误回调只给了通用提示,完全没法定位问题,先修改ErrorListener,打印并显示具体错误详情:

{ error ->
    val errorDetail = when {
        error.networkResponse != null -> {
            "HTTP状态码:${error.networkResponse.statusCode}\n错误内容:${String(error.networkResponse.data, Charsets.UTF_8)}"
        }
        else -> "请求失败:${error.message ?: "未知错误"}"
    }
    Toast.makeText(this, errorDetail, Toast.LENGTH_LONG).show()
    Log.e("NewsAPI_Error", errorDetail)
}

运行后就能拿到具体的错误原因,比如API密钥失效、字段不存在、网络权限缺失等。

2. 检查网络权限

确认AndroidManifest.xml中是否添加了必要的网络权限,没有的话Volley无法发起网络请求:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

3. 验证API URL的有效性

直接把你的APIurl复制到浏览器中打开,查看返回结果:

  • 如果返回提示API密钥无效,去NewsAPI官网检查密钥是否过期、是否开启了对应接口的访问权限
  • 如果返回的JSON中没有articles字段,或者author/urlToImage等字段为null,那么getString()会抛出JSONException,直接进入错误回调

4. 处理JSON字段为null的情况

NewsAPI返回的部分字段(如author、urlToImage)经常会是null,直接调用getString()会触发异常,改用optString()并设置默认值:

val news = News(
    currJsonObject.optString("title", "无标题"),
    currJsonObject.optString("author", "匿名作者"),
    currJsonObject.optString("url", ""),
    currJsonObject.optString("urlToImage", "")
)

5. 确认单例上下文的正确性

你的单例类使用context.applicationContext创建RequestQueue是正确的,但要确保调用MySingleton.getInstance(this)时,this是Activity或Application的上下文(Fragment中需使用requireContext())。

内容的提问来源于stack exchange,提问作者Divyansh Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:20:36