kotlin.UninitializedPropertyAccessException - lateinit 属性 mAdapter 尚未初始化 - Android 开发
kotlin.UninitializedPropertyAccessException - lateinit property mAdapter has not been initialized - Android Development
我正在 android 中制作一个新闻应用程序,但是当我从我的应用程序调用 API(http) 时出现错误。我不知道为什么会出现错误我实现了所有 class、memebers、函数。
请帮助我。
错误描述如下
2021-01-21 09:21:25.896 18052-18052/com.arne.khabriapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.arne.khabriapp, PID: 18052
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.arne.khabriapp/com.arne.khabriapp.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property mAdapter has not been initialized
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property mAdapter has not been initialized
at com.arne.khabriapp.MainActivity.onCreate(MainActivity.kt:25)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2021-01-21 09:21:25.912 18052-18090/com.arne.khabriapp D/NetworkSecurityConfig:
No Network Security Config specified, using platform default
这是我的MainActivity.kt
package com.arne.khabriapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.toolbox.JsonObjectRequest
class MainActivity : AppCompatActivity(), NewsItemClicked {
private lateinit var mAdapter: NewsListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.rView)
recyclerView.layoutManager = LinearLayoutManager(this)
// recyclerView.layoutManager = GridLayoutManager(this,12)
// recyclerView.layoutManager = StaggeredGridLayoutManager(15,12)
fetchData()
recyclerView.adapter = mAdapter
}
private fun fetchData() {
// val list = ArrayList<String>()
// for(i in 0 until 100){
// list.add("item $i")
// }
// return list
val url = "https://newsapi.org/v2/top-headlines?country=in&apiKey=9bb7bf6152d147ad8ba14cd0e7452f2f"
val jsonObjectRequest = JsonObjectRequest(
Request.Method.GET,
url,
null,
{
val newsJsonArray = it.getJSONArray("articles")
val newsArray = ArrayList<NewsClass>()
for (i in 0 until newsJsonArray.length()){
val newsJsonObject = newsJsonArray.getJSONObject(i)
val news =NewsClass(
newsJsonObject.getString("title"),
newsJsonObject.getString("author"),
newsJsonObject.getString("url"),
newsJsonObject.getString("urlToImage")
)
newsArray.add(news)
}
mAdapter.updateNews(newsArray)
},
{
}
)
MySingletonClass.getInstance(this).addRequestQueue(jsonObjectRequest)
}
override fun OnItemClick(item: NewsClass) {
}
}
这是我的NewsAdapter.kt
package com.arne.khabriapp
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
//class Name: extendItForRecyclerView.Adapter<ViewHolderClass>
class NewsListAdapter( private val listener: NewsItemClicked): RecyclerView.Adapter<NewsViewHolder>()
{
private val items: ArrayList<NewsClass> = ArrayList()
// call me when each time one viewholder is created
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsViewHolder {
//Layout Inflater - Converts XML into View
val view = LayoutInflater.from(parent.context).inflate(R.layout.itemnews, parent, false)
val viewHolder = NewsViewHolder(view)
view.setOnClickListener{
//this is a call back to main activity so the main activity knows that any item is clicked and then the mainn activity behave according to this.
listener.OnItemClick(items[viewHolder.adapterPosition])
}
return viewHolder
}
// I will bind the item with viewholder
override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {
val currentItem = items[position]
holder.titleView.text = currentItem.title
}
// call me only one time i will give you how many item will be here in list
override fun getItemCount(): Int {
return items.size
}
fun updateNews(updatedNews: ArrayList<NewsClass>){
items.clear()
items.addAll(updatedNews)
notifyDataSetChanged()
}
}
class NewsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val titleView: TextView = itemView.findViewById(R.id.title)
}
interface NewsItemClicked{
fun OnItemClick(item: NewsClass)
}
请回答
非常感谢您的进阶
你可以这样做。
private lateinit var mAdapter: NewsListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.rView)
recyclerView.layoutManager = LinearLayoutManager(this)
// recyclerView.layoutManager = GridLayoutManager(this,12)
// recyclerView.layoutManager = StaggeredGridLayoutManager(15,12)
mAdapter = NewsListAdapter(this)//should be inited before use.
fetchData()
recyclerView.adapter = mAdapter
}
或者你也可以这样做
private val mAdapter: NewsListAdapter by lazy{
NewsListAdapter(this)
}
我正在 android 中制作一个新闻应用程序,但是当我从我的应用程序调用 API(http) 时出现错误。我不知道为什么会出现错误我实现了所有 class、memebers、函数。 请帮助我。
错误描述如下
2021-01-21 09:21:25.896 18052-18052/com.arne.khabriapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.arne.khabriapp, PID: 18052
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.arne.khabriapp/com.arne.khabriapp.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property mAdapter has not been initialized
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property mAdapter has not been initialized
at com.arne.khabriapp.MainActivity.onCreate(MainActivity.kt:25)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2021-01-21 09:21:25.912 18052-18090/com.arne.khabriapp D/NetworkSecurityConfig:
No Network Security Config specified, using platform default
这是我的MainActivity.kt
package com.arne.khabriapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.toolbox.JsonObjectRequest
class MainActivity : AppCompatActivity(), NewsItemClicked {
private lateinit var mAdapter: NewsListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.rView)
recyclerView.layoutManager = LinearLayoutManager(this)
// recyclerView.layoutManager = GridLayoutManager(this,12)
// recyclerView.layoutManager = StaggeredGridLayoutManager(15,12)
fetchData()
recyclerView.adapter = mAdapter
}
private fun fetchData() {
// val list = ArrayList<String>()
// for(i in 0 until 100){
// list.add("item $i")
// }
// return list
val url = "https://newsapi.org/v2/top-headlines?country=in&apiKey=9bb7bf6152d147ad8ba14cd0e7452f2f"
val jsonObjectRequest = JsonObjectRequest(
Request.Method.GET,
url,
null,
{
val newsJsonArray = it.getJSONArray("articles")
val newsArray = ArrayList<NewsClass>()
for (i in 0 until newsJsonArray.length()){
val newsJsonObject = newsJsonArray.getJSONObject(i)
val news =NewsClass(
newsJsonObject.getString("title"),
newsJsonObject.getString("author"),
newsJsonObject.getString("url"),
newsJsonObject.getString("urlToImage")
)
newsArray.add(news)
}
mAdapter.updateNews(newsArray)
},
{
}
)
MySingletonClass.getInstance(this).addRequestQueue(jsonObjectRequest)
}
override fun OnItemClick(item: NewsClass) {
}
}
这是我的NewsAdapter.kt
package com.arne.khabriapp
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
//class Name: extendItForRecyclerView.Adapter<ViewHolderClass>
class NewsListAdapter( private val listener: NewsItemClicked): RecyclerView.Adapter<NewsViewHolder>()
{
private val items: ArrayList<NewsClass> = ArrayList()
// call me when each time one viewholder is created
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsViewHolder {
//Layout Inflater - Converts XML into View
val view = LayoutInflater.from(parent.context).inflate(R.layout.itemnews, parent, false)
val viewHolder = NewsViewHolder(view)
view.setOnClickListener{
//this is a call back to main activity so the main activity knows that any item is clicked and then the mainn activity behave according to this.
listener.OnItemClick(items[viewHolder.adapterPosition])
}
return viewHolder
}
// I will bind the item with viewholder
override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {
val currentItem = items[position]
holder.titleView.text = currentItem.title
}
// call me only one time i will give you how many item will be here in list
override fun getItemCount(): Int {
return items.size
}
fun updateNews(updatedNews: ArrayList<NewsClass>){
items.clear()
items.addAll(updatedNews)
notifyDataSetChanged()
}
}
class NewsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val titleView: TextView = itemView.findViewById(R.id.title)
}
interface NewsItemClicked{
fun OnItemClick(item: NewsClass)
}
请回答 非常感谢您的进阶
你可以这样做。
private lateinit var mAdapter: NewsListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.rView)
recyclerView.layoutManager = LinearLayoutManager(this)
// recyclerView.layoutManager = GridLayoutManager(this,12)
// recyclerView.layoutManager = StaggeredGridLayoutManager(15,12)
mAdapter = NewsListAdapter(this)//should be inited before use.
fetchData()
recyclerView.adapter = mAdapter
}
或者你也可以这样做
private val mAdapter: NewsListAdapter by lazy{
NewsListAdapter(this)
}