使用Retrofit+Moshi调用API无响应,Android新闻App求助
问题描述
我正在学习Android开发,尝试搭建一个简易新闻App,但已卡壳3天无法从服务器获取JSON响应。怀疑Retrofit调用存在问题却找不到原因,Logcat中无响应输出(已替换个人API密钥)。
相关代码
private const val BASE_URL = "https://newsapi.org" private val moshi = Moshi.Builder() .add(KotlinJsonAdapterFactory()) .build() private val retrofit = Retrofit.Builder() .addConverterFactory(MoshiConverterFactory.create(moshi)) .baseUrl(BASE_URL) .build() interface CallNewsApi { @GET("/v2/top-headlines") suspend fun getHeadlines( @Query("apiKey") key: String, @Query("category") category: String, @Query("country") country: String ): Response<NewsApiResponse> } object NewsApi { val retrofitService: CallNewsApi by lazy { retrofit.create(CallNewsApi::class.java) } } data class NewsApiResponse( var status: String, var totalResults: Int, var articles: List<NewsHeadlines> ) data class NewsHeadlines( var source: Source, var author: String, var title: String, var description: String, var url: String, var urlToImage: String, var publishedAt: String, var content: String ) data class Source( var id: String, var name: String ) class NewsViewModel : ViewModel() { private val _newsList = MutableLiveData<List<NewsHeadlines>>() val status: LiveData<List<NewsHeadlines>> = _newsList init { getNewsLines() } private fun getNewsLines() { viewModelScope.launch { try { Log.d("ViewModel"," before retrofit") val call = NewsApi.retrofitService.getHeadlines( "myApiKey", "sports", "il" ) Log.d("ViewModel", call.body().toString()) } catch (e: java.lang.Exception) { _newsList.value = listOf() } } } }
问题排查与修复方案
1. 未处理响应状态与错误信息
当前代码仅打印响应体,未检查请求是否成功,也未捕获并打印请求失败的状态码、错误信息及异常栈,导致无法定位问题。修改getNewsLines方法:
private fun getNewsLines() { viewModelScope.launch { try { Log.d("ViewModel"," before retrofit") val response = NewsApi.retrofitService.getHeadlines( "myApiKey", "sports", "il" ) if (response.isSuccessful) { Log.d("ViewModel", "响应成功: ${response.body().toString()}") response.body()?.let { _newsList.value = it.articles } ?: Log.e("ViewModel", "响应体为空") } else { Log.e("ViewModel", "请求失败,状态码: ${response.code()}") response.errorBody()?.let { Log.e("ViewModel", "错误详情: ${it.string()}") } } } catch (e: Exception) { Log.e("ViewModel", "请求异常", e) _newsList.value = listOf() } } }
2. 数据类字段未兼容空值
NewsAPI返回的部分字段(如author、source.id、urlToImage)可能为null,当前数据类使用非空类型会导致Moshi解析抛出异常。修改数据类为可空类型:
data class NewsHeadlines( var source: Source, var author: String?, var title: String, var description: String?, var url: String, var urlToImage: String?, var publishedAt: String, var content: String? ) data class Source( var id: String?, var name: String )
3. 基础配置检查
- 确认
AndroidManifest.xml已添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> - 用浏览器/Postman直接访问接口链接(替换真实API密钥),验证接口本身是否能返回有效数据:
https://newsapi.org/v2/top-headlines?apiKey=你的密钥&category=sports&country=il - 检查API密钥有效性:确认密钥未过期、未超出请求次数限制,且允许当前App包名访问。
内容的提问来源于stack exchange,提问作者Sami Kassoum
相关产品推荐
相关产品推荐

