使用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
相关产品推荐
相关产品推荐

