I’m facing an issue with requestHandler… Maybe i’m not seeing a specific issue. but i checked the code several times and compared it with the code provided from BNR but couldn’t find the missing part…
I get this error:
kotlin.UninitializedPropertyAccessException: lateinit property requestHandler has not been initialized at com.bignerdranch.android.photogallery.ThumbnailDownloader.queueThumbnail(ThumbnailDownloader.kt:94)
this code is being called by the Recyclerview as you know in the PhotoGalleryFragment
override fun onBindViewHolder(holder: PhotoHolder, position: Int) {
val galleryItem = galleryItems[position]
//holder.bindTitle(galleryItem.title)
val placeholder: Drawable = ContextCompat.getDrawable(
requireContext(),
R.drawable.hala_atamleh
)?: ColorDrawable()
holder.bindTitle(placeholder) //should be bindDrawable but it didn't work
thumbnailDownloader.queueThumbnail(holder, galleryItem.url) //page 515
}
what did i missed to get this error?
here is the file code:
package com.bignerdranch.android.photogallery
import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.os.Message
import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import java.util.concurrent.ConcurrentHashMap
private const val TAG = "ThumbnailDownloader"
private const val MESSAGE_DOWNLOAD = 0
class ThumbnailDownloader<in T>(private val responseHandler: Handler, //page. 524
private val onThumbnailDownloaded : (T, Bitmap) -> Unit)
: HandlerThread(TAG) /*, LifecycleObserver page 512*/ { //page. 510
private lateinit var requestHandler: Handler //page516++
private var hasQuit = false
private val requestMap = ConcurrentHashMap<T, String>()
private val flickrFetchr = FlickrFetchr()
val fragmentLifecycleObserver: LifecycleObserver = //page 527
object : LifecycleObserver{
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun setup() {
Log.i(TAG, "Starting background thread")
start() //page 514
looper
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun tearDown() {
Log.i(TAG, "Destroying background thread")
quit()
}
}
@Suppress("UNCHECKED_CAST") //page 522
@SuppressLint("HandlerLeak")
override fun onLooperPrepared() {
requestHandler = object : Handler(Looper.getMainLooper()){
override fun handleMessage(msg: Message) {
if (msg.what == MESSAGE_DOWNLOAD){
val target = msg.obj as T
Log.i(TAG, "Got a request for URL: ${requestMap[target]}")
handleRequest(target)
}
}
}
}
//page 528
val viewLifecycleObserver : LifecycleObserver =
object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun tearDown(){
Log.i(TAG, "Clearing all requests from Queue")
requestHandler.removeMessages(MESSAGE_DOWNLOAD)
requestMap.clear()
}
}
override fun quit(): Boolean {
hasQuit = true
return super.quit()
}
fun queueThumbnail(target: T, url: String){ //page 510
Log.i(TAG, "Got a URL: $url")
requestMap[target] = url //page 521
requestHandler.obtainMessage(MESSAGE_DOWNLOAD, target)
.sendToTarget()
}
fun clearQueue() {
requestHandler.removeMessages(MESSAGE_DOWNLOAD)
requestMap.clear()
}
private fun handleRequest(target: T){
val url = requestMap[target] ?: return
val bitmap = flickrFetchr.fetchPhoto(url) ?: return
responseHandler.post(Runnable { //page.526
if(requestMap[target] != url || hasQuit){
return@Runnable
}
requestMap.remove(target)
onThumbnailDownloaded(target, bitmap)
})
}
}
why do you write - requestHandler = object : Handler(Looper.getMainLooper())? it is not main looper. I think you need write: requestHandler = object : Handler() {…
I remember that was deprecated, and later on i changed library version and worked on it that way…
‘constructor Handler()’ is deprecated. Deprecated in Java
Default constructor associates this handler with the Looper for the current thread. If this thread does not have a looper, this handler won’t be able to receive messages so an exception is thrown.
after all when i rebuilt the app for paging 3 i used glide…
How about val viewLifecycleObserver? There is function clearQueue() but when I am deleting whole val then I have error in PhotoGalleryFragment because there is unresolved reference: viewLifecycleObserver
val fragmentLifecycleObserver: DefaultLifecycleObserver =
object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
Log.i(TAG, "Starting background thread")
start()
looper
}
override fun onDestroy(owner: LifecycleOwner) {
Log.i(TAG, "Destroying background thread")
quit()
}
}
val viewLifecycleObserver: DefaultLifecycleObserver =
object : DefaultLifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun clearQueue() {
Log.i (TAG, "Clearing all requests from queue")
requestHandler.removeMessages(MESSAGE_DOWNLOAD)
requestMap.clear()
}
}