Good day, I'm using Retrofit for the first time and I can't seem to get it to work. working on an app that get crypto currency rates in local currencies, here is the api [link], JSON format
Here are my models for News
data class News(
@field:SerializedName("totalResults")
val totalResults: Int,
@field:SerializedName("articles")
val articles: List<NewsArticle>?=null,
@field:SerializedName("status")
val status: String)
My model calss for NewsArticles:
data class NewsArticle(
@field:SerializedName("urlToImage")
val urlToImage: String? = null,
@field:SerializedName("description")
val description: String? = null,
@field:SerializedName("title")
val title: String? = null,
@field:SerializedName("url")
val url: String? = null,)
My interface:
const val BASE_URL = "https://saurav.tech/NewsAPI/"
interface NewsApiService {
@GET("top-headlines.json")
fun getNews(
@Query("category") category: String,
@Query("country_code") country_code: String
): Call<News>}
object NewsApi{
val newsInstance:NewsApiService
init {
val retrofit=Retrofit.Builder()
.baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create())
.build()
newsInstance=retrofit.create(NewsApiService::class.java)
}
}
My MainActivity class
class MainActivity : AppCompatActivity() {
private lateinit var adapter: NewsAdapter
//var totalResult=1
private var article = mutableListOf<NewsArticle>()
lateinit var refreshLayout: SwipeRefreshLayout
private lateinit var recyclerView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView = findViewById(R.id.recyclerViewNews)
refreshLayout = findViewById(R.id.refreshLayout)
adapter = NewsAdapter(this@MainActivity, article)
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(this@MainActivity)
fetchNews()
}
private fun fetchNews() {
val news = NewsApi.newsInstance.getNews("technology", "in")
news.enqueue(object : Callback<News> {
override fun onResponse(call: Call<News>, response: Response<News>) {
val news = response.body()
article.addAll(news!!.articles)
}
override fun onFailure(call: Call<News>, t: Throwable) {
Toast.makeText(applicationContext, t.message, Toast.LENGTH_SHORT).show()
}
})
}
}
My AdapterClass:
class NewsAdapter(val context: Context, val newsArticles: MutableList<NewsArticle>) :
RecyclerView.Adapter<NewsAdapter.NewsViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.news_items, parent, false)
return NewsViewHolder(view)
}
override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {
val article = newsArticles[position]
holder.title.text = article.title
holder.description.text = article.description
Glide.with(holder.itemView.context).load(article.urlToImage).into(holder.image)
}
override fun getItemCount() = newsArticles.size
class NewsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val title = view.findViewById<TextView>(R.id.titleText)!!
val description = view.findViewById<TextView>(R.id.descriptionText)!!
val image = view.findViewById<ImageView>(R.id.NewsImage)!!
}
}
When I run the code and check my log I get this error:
java.lang.NullPointerException
at com.ashish.technews.uis.MainActivity$fetchNews$1.onResponse(MainActivity.kt:44)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
at retrofit2.-$$Lambda$DefaultCallAdapterFactory$ExecutorCallbackCall$1$hVGjmafRi6VitDIrPNdoFizVAdk.run(lambda)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:165)
at android.app.ActivityThread.main(ActivityThread.java:6375)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)