I am trying to get unique numbers from call logs of a user and show them in a RecyclerView
. By unique I mean if I have shown the number, or corresponding contact once in the list, I have to skip the item. And I want to use a Cursor
for showing this to make the rendering quick.
To do this, I have implemented a RecyclerView
Adapter which looks like this (Only showing the relevant code, kotlin)
class CallAdapter(val activity: Activity, var cursor: Cursor) : RecyclerView.Adapter<CallAdapter.ViewHolder>() {
val handler = Handler()
val contacts = ArrayList<Contact>()
init {
cursor.moveToFirst()
UniqueLogs(this).start()
}
companion object {
const val TAG = "CallAdapter"
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(activity)
val binding = CallLogItemBinding.inflate(inflater, parent, false)
return ViewHolder(binding)
}
override fun getItemCount(): Int {
return contacts.count()
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val contact = contacts[position]
...
cursor.moveToNext()
}
class ViewHolder(val binding: CallLogItemBinding) : RecyclerView.ViewHolder(binding.root)
class UniqueLogs(val adapter: CallLogAdapterShobhit) : Thread() {
private var available = true
private val cursor = adapter.cursor
private val hash: HashMap<String, Int> = HashMap<String, Int>()
private val contacts = adapter.contacts
private var count = 0
override fun run() {
cursor.moveToFirst()
while (available && cursor.moveToNext()) {
var contact = adapter.getCurrentItemContact()
while (available && hash[contact.phoneNumber] == 1) {
if (cursor.moveToNext()) {
contact = adapter.getCurrentItemContact()
} else {
available = false
}
}
if (available) {
contacts.add(contact)
val position = count
count += 1
adapter.handler.post({
Log.d(TAG, "Position: $position Size: ${adapter.itemCount}")
adapter.notifyItemInserted(position)
})
hash[contact.phoneNumber] = 1
}
}
}
}
}
When I run this code, I am getting an exception which looks like this :-
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{c75176c position=5 id=-1, oldPos=4, pLpos:4 scrap [attachedScrap] tmpDetached not recyclable(1) no parent}
The position
, id
, oldPos
, pLpos
, etc. are different every time but the error is essentially the same.
I've tried writing logs as well to make sure that I am not trying to insert an element before the element is added to contacts
array list, but the logs say that all's well.
Any idea what might be wrong here?