[英]kotlin.UninitializedPropertyAccessException: lateinit property roomClickedInterface has not been initialized
I am trying to follow Pusher Chatkit's tutorial for "BUILDING A GROUP CHAT APP USING KOTLIN AND PUSHER CHATKIT" however I am running into an issue with the Recycler View adapter.我正在尝试遵循 Pusher Chatkit 的“使用 KOTLIN 和 PUSHER CHATKIT 构建群聊应用程序”的教程,但是我遇到了 Recycler View 适配器的问题。 FYI, I am still learning Kotlin.仅供参考,我仍在学习 Kotlin。 I've been reading up on lateinit vars but I can't find anything that addresses this case.我一直在阅读有关 lateinit vars 的内容,但我找不到任何可以解决这种情况的内容。 The error occurs in the recycler view adapter.错误发生在回收器视图适配器中。
This is the error I get:这是我得到的错误:
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.access$3100(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 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 Adapter 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)
}
}
Any and all help is appreciated.任何和所有的帮助表示赞赏。
lateinit
means late initialization.lateinit
表示延迟初始化。 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.如果您不想在构造函数中初始化变量,而是想稍后初始化它,并且如果您可以在使用之前保证初始化,则使用lateinit
关键字声明该变量。 It will not allocate memory until initialized.它在初始化之前不会分配内存。
So, You have to initialize the lateinit
property before try to use it.因此,您必须在尝试使用它之前初始化lateinit
属性。
Option - 1: Call setInterface()
to initialize the property before click the list item.选项 - 1:在单击列表项之前调用setInterface()
来初始化属性。 You can also check whether a lateinit
var has already been initialized or not using .isInitialized
like below:您还可以检查是否lateinit
变种已经初始化或不使用.isInitialized
象下面这样:
override fun onClick(p0: View?) {
if(this::roomClickedInterface.isInitialized) {
roomClickedInterface.roomSelected(list[adapterPosition])
}
}
Option - 2: Remove lateinit
property from your adapter and also it's setter选项 - 2:从您的适配器中删除lateinit
属性以及它的设置器
//lateinit var roomClickedInterface:RoomClickedInterface
And pass RoomClickedInterface
as parameter of your adapter's constructor并将RoomClickedInterface
作为适配器构造函数的参数传递
class ChatRoomsListAdapter(val roomClickedInterface:RoomClickedInterface):
RecyclerView.Adapter<ChatRoomsListAdapter.ViewHolder>() {
//Implementation
}
Option - 3: Remove lateinit
and use nullable
property选项 - 3:删除lateinit
并使用nullable
属性
private var roomClickedInterface: RoomClickedInterface? = null
And then use like below using null
safety notation ?.
然后像下面这样使用null
安全符号?.
: :
override fun onClick(p0: View?) {
roomClickedInterface?.roomSelected(list[adapterPosition])
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.