androidandroid-layoutkotlinandroid-recyclerviewkotlin-lateinit

"kotlin.UninitializedPropertyAccessException: lateinit property madapter has not been initialized at..." when setting up RecyclerView Adapter


Line throwing error:

recyclerView.adapter = mAdapter

Code:

class MainActivity : AppCompatActivity(), NewsItemClicked {
    private lateinit var recyclerView:RecyclerView
    private lateinit var mAdapter: NewsListAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        recyclerView = findViewById(R.id.recyclerView)
        fetchData()

        val verticalLayoutManager = LinearLayoutManager(this)
             recyclerView.layoutManager = verticalLayoutManager
        recyclerView.adapter = mAdapter
    }

    private fun fetchData() {
        val url =
            "https://newsapi.org/v2/top-headlines?country=in&apiKey=*****"
        val jsonObjectRequest = JsonObjectRequest(
            Request.Method.GET,
            url,
            null,
            {
                val newsJsonArray = it.getJSONArray("articles")
                val newsArray = ArrayList<News>()
                for (i in 0 until newsJsonArray.length()) {
                    val newsJsonObject = newsJsonArray.getJSONObject(i)
                    val news = News(
                        newsJsonObject.getString("title"),
                        newsJsonObject.getString("author"),
                        newsJsonObject.getString("url"),
                        newsJsonObject.getString("urlToImage")
                    )
                    newsArray.add(news)
                }
                mAdapter.updateNews(newsArray)
            }, {

            }

        )
        MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest)
    }
    override fun onItemClicked(item: News) {
        val builder = CustomTabsIntent.Builder()
        val customTabsIntent = builder.build()
        customTabsIntent.launchUrl(this, Uri.parse(item.url))
    }
}

Error from logcat:

2021-01-19 18:38:40.819 3869-3869/com.example.newsfresh E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.newsfresh, PID: 3869
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.newsfresh/com.example.newsfresh.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property madapter has not been initialized
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2895)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1616)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:176)
        at android.app.ActivityThread.main(ActivityThread.java:6651)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
     Caused by: kotlin.UninitializedPropertyAccessException: lateinit property madapter has not been initialized
        at com.example.newsfresh.MainActivity.onCreate(MainActivity.kt:25)
        at android.app.Activity.performCreate(Activity.java:7088)
        at android.app.Activity.performCreate(Activity.java:7079)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2895) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1616) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:176) 
        at android.app.ActivityThread.main(ActivityThread.java:6651) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824) 

Solution

  • You have not initialized your lateinit var mAdapter variable.

    Kotlin allows you to access it despite it being uninitialized because it's lateinit, but it will throw this exception. You could solve this one of two ways:

    Remove lateinit, initialize at declaration site:

    In this case, it could be a val:

    private val mAdapter = NewsListAdapter(...)
    

    This assumes that you have everything needed to set up the adapter when the Activity is started. You'll likely need to call one of the notify... methods on it once data is available.

    If you don't...

    Make sure it's initialized before you use it

    mAdapter = NewsListAdapter(...)
    recyclerView.adapter = mAdapter