kotlin.UninitializedPropertyAccessException: lateinit 属性 roomClickedInterface 尚未初始化
kotlin.UninitializedPropertyAccessException: lateinit property roomClickedInterface has not been initialized
我正在尝试按照 "BUILDING A GROUP CHAT APP USING KOTLIN AND PUSHER CHATKIT" 的 Pusher Chatkit 教程进行操作,但是我 运行 遇到了 Recycler View 适配器的问题。仅供参考,我仍在学习 Kotlin。我一直在阅读有关 lateinit vars 的内容,但我找不到任何可以解决这种情况的内容。错误发生在回收器视图适配器中。
这是我得到的错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android_myneighborsbookshelf, PID: 26692
kotlin.UninitializedPropertyAccessException: lateinit property roomClickedInterface has not been initialized
at com.example.android_myneighborsbookshelf.adapters.ChatRoomsListAdapter.getRoomClickedInterface(ChatRoomsListAdapter.kt:13)
at com.example.android_myneighborsbookshelf.adapters.ChatRoomsListAdapter$ViewHolder.onClick(ChatRoomsListAdapter.kt:66)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access00(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
ChatRoomsListActivity.kt
class ChatRoomsListActivity : AppCompatActivity() {
val adapter = ChatRoomsListAdapter();
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat_room_list)
initRecyclerView()
initChatManager()
}
private fun initRecyclerView() {
recycler_view.layoutManager = LinearLayoutManager(this@ChatRoomsListActivity)
recycler_view.adapter = adapter
}
private fun initChatManager() {
val chatManager = ChatManager(
instanceLocator = "blahblahblah",
userId = "username1-PCKid",
dependencies = AndroidChatkitDependencies(
tokenProvider = ChatkitTokenProvider(
endpoint = "blahblahblah",
// endpoint = "http://10.0.2.2:3000/auth",
userId = "username1-PCKid"
)
)
)
chatManager.connect(listeners = ChatListeners(
onErrorOccurred = { },
onAddedToRoom = { },
onRemovedFromRoom = { },
onCurrentUserReceived = { },
onNewReadCursor = { },
onRoomDeleted = { },
onRoomUpdated = { },
onPresenceChanged = { u, n, p -> },
onUserJoinedRoom = { u, r -> },
onUserLeftRoom = { u, r -> },
onUserStartedTyping = { u, r -> },
onUserStoppedTyping = { u, r -> }
)) { result ->
when (result) {
is Result.Success -> {
// We have connected!
val currentUser = result.value
AppController.currentUser = currentUser
val userJoinedRooms = ArrayList<Room>(currentUser.rooms)
for (i in 0 until userJoinedRooms.size) {
adapter.addRoom(userJoinedRooms[i])
}
currentUser.getJoinableRooms { result ->
when (result) {
is Result.Success -> {
// Do something with List<Room>
val rooms = result.value
runOnUiThread {
for (i in 0 until rooms.size) {
adapter.addRoom(rooms[i])
}
}
}
}
}
adapter.setInterface(object : ChatRoomsListAdapter.RoomClickedInterface {
override fun roomSelected(room: Room) {
if (room.memberUserIds.contains(currentUser.id)) {
// user already belongs to this room
roomJoined(room)
} else {
currentUser.joinRoom(
roomId = room.id,
callback = { result ->
when (result) {
is Result.Success -> {
// Joined the room!
roomJoined(result.value)
}
is Result.Failure -> {
Log.d("TAG", result.error.toString())
}
}
}
)
}
}
})
}
is Result.Failure -> {
// Failure
Log.d("TAG", result.error.toString())
}
}
}
}
private fun roomJoined(room: Room) {
val intent = Intent(this@ChatRoomsListActivity, ChatRoomsListActivity::class.java)
intent.putExtra("room_id", room.id)
intent.putExtra("room_name", room.name)
startActivity(intent)
}
}
RecyclerView 适配器
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.pusher.chatkit.rooms.Room
import android.view.LayoutInflater
import androidx.recyclerview.widget.RecyclerView
import com.example.android_myneighborsbookshelf.R
class ChatRoomsListAdapter: RecyclerView.Adapter<ChatRoomsListAdapter.ViewHolder>() {
private var list = ArrayList<Room>()
lateinit var roomClickedInterface:RoomClickedInterface // <-- Error occurs here - kt.13
fun addRoom(room:Room){
list.add(room)
notifyDataSetChanged()
}
fun setInterface(roomClickedInterface:RoomClickedInterface){
this.roomClickedInterface = roomClickedInterface
}
override fun getItemCount(): Int {
return list.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(
android.R.layout.simple_list_item_1,
parent,
false
)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.roomName.text = list[position].name
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView), View.OnClickListener {
override fun onClick(p0: View?) {
roomClickedInterface.roomSelected(list[adapterPosition]) // <-- Error occurs here kt.66
}
var roomName: TextView = itemView.findViewById(android.R.id.text1)
init {
itemView.setOnClickListener(this)
}
}
interface RoomClickedInterface{
fun roomSelected(room:Room)
}
}
感谢任何帮助。
lateinit
means late initialization. If you do not want to initialize
a variable in the constructor, instead you want to initialize it later
on and if you can guarantee the initialization before using it, then
declare that variable with lateinit
keyword. It will not allocate
memory until initialized.
因此,您必须先初始化 lateinit
属性,然后再尝试使用它。
选项 - 1: 在单击列表项之前调用 setInterface()
初始化 属性。您还可以使用 .isInitialized
检查 lateinit
var 是否已经初始化,如下所示:
override fun onClick(p0: View?) {
if(this::roomClickedInterface.isInitialized) {
roomClickedInterface.roomSelected(list[adapterPosition])
}
}
选项 - 2: 从您的适配器中删除 lateinit
属性 并且它也是 setter
//lateinit var roomClickedInterface:RoomClickedInterface
并传递 RoomClickedInterface
作为适配器构造函数的参数
class ChatRoomsListAdapter(val roomClickedInterface:RoomClickedInterface):
RecyclerView.Adapter<ChatRoomsListAdapter.ViewHolder>() {
//Implementation
}
选项 - 3: 删除 lateinit
并使用 nullable
属性
private var roomClickedInterface: RoomClickedInterface? = null
然后像下面这样使用 null
安全符号 ?.
:
override fun onClick(p0: View?) {
roomClickedInterface?.roomSelected(list[adapterPosition])
}
我正在尝试按照 "BUILDING A GROUP CHAT APP USING KOTLIN AND PUSHER CHATKIT" 的 Pusher Chatkit 教程进行操作,但是我 运行 遇到了 Recycler View 适配器的问题。仅供参考,我仍在学习 Kotlin。我一直在阅读有关 lateinit vars 的内容,但我找不到任何可以解决这种情况的内容。错误发生在回收器视图适配器中。
这是我得到的错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android_myneighborsbookshelf, PID: 26692
kotlin.UninitializedPropertyAccessException: lateinit property roomClickedInterface has not been initialized
at com.example.android_myneighborsbookshelf.adapters.ChatRoomsListAdapter.getRoomClickedInterface(ChatRoomsListAdapter.kt:13)
at com.example.android_myneighborsbookshelf.adapters.ChatRoomsListAdapter$ViewHolder.onClick(ChatRoomsListAdapter.kt:66)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access00(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
ChatRoomsListActivity.kt
class ChatRoomsListActivity : AppCompatActivity() {
val adapter = ChatRoomsListAdapter();
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat_room_list)
initRecyclerView()
initChatManager()
}
private fun initRecyclerView() {
recycler_view.layoutManager = LinearLayoutManager(this@ChatRoomsListActivity)
recycler_view.adapter = adapter
}
private fun initChatManager() {
val chatManager = ChatManager(
instanceLocator = "blahblahblah",
userId = "username1-PCKid",
dependencies = AndroidChatkitDependencies(
tokenProvider = ChatkitTokenProvider(
endpoint = "blahblahblah",
// endpoint = "http://10.0.2.2:3000/auth",
userId = "username1-PCKid"
)
)
)
chatManager.connect(listeners = ChatListeners(
onErrorOccurred = { },
onAddedToRoom = { },
onRemovedFromRoom = { },
onCurrentUserReceived = { },
onNewReadCursor = { },
onRoomDeleted = { },
onRoomUpdated = { },
onPresenceChanged = { u, n, p -> },
onUserJoinedRoom = { u, r -> },
onUserLeftRoom = { u, r -> },
onUserStartedTyping = { u, r -> },
onUserStoppedTyping = { u, r -> }
)) { result ->
when (result) {
is Result.Success -> {
// We have connected!
val currentUser = result.value
AppController.currentUser = currentUser
val userJoinedRooms = ArrayList<Room>(currentUser.rooms)
for (i in 0 until userJoinedRooms.size) {
adapter.addRoom(userJoinedRooms[i])
}
currentUser.getJoinableRooms { result ->
when (result) {
is Result.Success -> {
// Do something with List<Room>
val rooms = result.value
runOnUiThread {
for (i in 0 until rooms.size) {
adapter.addRoom(rooms[i])
}
}
}
}
}
adapter.setInterface(object : ChatRoomsListAdapter.RoomClickedInterface {
override fun roomSelected(room: Room) {
if (room.memberUserIds.contains(currentUser.id)) {
// user already belongs to this room
roomJoined(room)
} else {
currentUser.joinRoom(
roomId = room.id,
callback = { result ->
when (result) {
is Result.Success -> {
// Joined the room!
roomJoined(result.value)
}
is Result.Failure -> {
Log.d("TAG", result.error.toString())
}
}
}
)
}
}
})
}
is Result.Failure -> {
// Failure
Log.d("TAG", result.error.toString())
}
}
}
}
private fun roomJoined(room: Room) {
val intent = Intent(this@ChatRoomsListActivity, ChatRoomsListActivity::class.java)
intent.putExtra("room_id", room.id)
intent.putExtra("room_name", room.name)
startActivity(intent)
}
}
RecyclerView 适配器
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.pusher.chatkit.rooms.Room
import android.view.LayoutInflater
import androidx.recyclerview.widget.RecyclerView
import com.example.android_myneighborsbookshelf.R
class ChatRoomsListAdapter: RecyclerView.Adapter<ChatRoomsListAdapter.ViewHolder>() {
private var list = ArrayList<Room>()
lateinit var roomClickedInterface:RoomClickedInterface // <-- Error occurs here - kt.13
fun addRoom(room:Room){
list.add(room)
notifyDataSetChanged()
}
fun setInterface(roomClickedInterface:RoomClickedInterface){
this.roomClickedInterface = roomClickedInterface
}
override fun getItemCount(): Int {
return list.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(
android.R.layout.simple_list_item_1,
parent,
false
)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.roomName.text = list[position].name
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView), View.OnClickListener {
override fun onClick(p0: View?) {
roomClickedInterface.roomSelected(list[adapterPosition]) // <-- Error occurs here kt.66
}
var roomName: TextView = itemView.findViewById(android.R.id.text1)
init {
itemView.setOnClickListener(this)
}
}
interface RoomClickedInterface{
fun roomSelected(room:Room)
}
}
感谢任何帮助。
lateinit
means late initialization. If you do not want to initialize a variable in the constructor, instead you want to initialize it later on and if you can guarantee the initialization before using it, then declare that variable withlateinit
keyword. It will not allocate memory until initialized.
因此,您必须先初始化 lateinit
属性,然后再尝试使用它。
选项 - 1: 在单击列表项之前调用 setInterface()
初始化 属性。您还可以使用 .isInitialized
检查 lateinit
var 是否已经初始化,如下所示:
override fun onClick(p0: View?) {
if(this::roomClickedInterface.isInitialized) {
roomClickedInterface.roomSelected(list[adapterPosition])
}
}
选项 - 2: 从您的适配器中删除 lateinit
属性 并且它也是 setter
//lateinit var roomClickedInterface:RoomClickedInterface
并传递 RoomClickedInterface
作为适配器构造函数的参数
class ChatRoomsListAdapter(val roomClickedInterface:RoomClickedInterface):
RecyclerView.Adapter<ChatRoomsListAdapter.ViewHolder>() {
//Implementation
}
选项 - 3: 删除 lateinit
并使用 nullable
属性
private var roomClickedInterface: RoomClickedInterface? = null
然后像下面这样使用 null
安全符号 ?.
:
override fun onClick(p0: View?) {
roomClickedInterface?.roomSelected(list[adapterPosition])
}