0

我的项目中有一个片段:

private const val TAG = "PhotoGalleryFragment"

class PhotoGalleryFragment: Fragment() {
  private lateinit var photoRecyclerView: RecyclerView
  private lateinit var photoGalleryViewModel: PhotoGalleryViewModel
  private lateinit var thumbnailDownloader: ThumbnailDownloader<PhotoHolder>

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    retainInstance = true
    photoGalleryViewModel = ViewModelProvider(this).get(PhotoGalleryViewModel::class.java)

    thumbnailDownloader = ThumbnailDownloader()
    lifecycle.addObserver(thumbnailDownloader)
  }

  override fun onCreateView (inflater: LayoutInflater,
                             container: ViewGroup?,
                             savedInstanceState: Bundle?): View?
  {
    val view = inflater.inflate(R.layout.fragment_photo_gallery, container, false)

    photoRecyclerView = view.findViewById(R.id.photo_recycler_view)
    photoRecyclerView.layoutManager = GridLayoutManager(context, 3)

    return view
  }

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    photoGalleryViewModel.galleryItemLiveData.observe(viewLifecycleOwner,
      Observer { galleryItems ->
        photoRecyclerView.adapter = PhotoAdapter(galleryItems)
      }
    )
  }

  private class PhotoHolder(imageView: ImageView) : RecyclerView.ViewHolder(imageView) {
    val bindDrawable: (Drawable) -> Unit = imageView::setImageDrawable
  }

  private inner class PhotoAdapter(private val galleryItems: List<GalleryItem>):
    RecyclerView.Adapter<PhotoHolder>()
  {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PhotoHolder
    {
      val view = layoutInflater.inflate(R.layout.list_item_gallery, parent, false)
          as ImageView
      return PhotoHolder(view)
    }

    override fun getItemCount(): Int = galleryItems.size

    override fun onBindViewHolder(holder: PhotoHolder, position: Int) {
      val galleryItem = galleryItems[position]
      val placeholder: Drawable = ContextCompat.getDrawable(requireContext(),
        R.drawable.bill_up_close) ?: ColorDrawable()
      holder.bindDrawable(placeholder)
      thumbnailDownloader.queueThumbnail(holder, galleryItem.url)
    }
  }

  override fun onDestroy() {
    super.onDestroy()
    lifecycle.removeObserver(thumbnailDownloader)
  }

  companion object {
    fun newInstance() = PhotoGalleryFragment()
  }
}

而且我在后台线程中有一个从 Flickr 下载缩略图的类:

private const val TAG = "ThumbnailDownloader"
private const val MESSAGE_DOWNLOAD = 0

class ThumbnailDownloader<in T> : HandlerThread(TAG), LifecycleObserver {
  private var hasQuit = false
  private lateinit var requestHandler: Handler
  private val requestMap = ConcurrentHashMap<T, String>()
  private val flickr = Flickr(ApiSingleton.get().flickr)

  override fun quit(): Boolean {
    hasQuit = true
    return super.quit()
  }

  fun queueThumbnail (target: T, url: String) {
    Log.i (TAG, "Got a url: $url")
    requestMap[target] = url
    requestHandler = Handler()
    requestHandler.obtainMessage(MESSAGE_DOWNLOAD, target).sendToTarget()
  }

  @Suppress("UNCHECKED_CAST")
  @SuppressLint("HandlerLeak")
  override fun onLooperPrepared() {
    requestHandler = object : Handler() {
      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)
        }
      }
    }
  }

  private fun handleRequest(target: T) {
    val url = requestMap[target] ?: return
    val bitmap = flickr.fetchPhoto(url) ?: return
  }

  @OnLifecycleEvent (Lifecycle.Event.ON_CREATE)
  fun setup() {
    Log.i (TAG,"Starting background thread")
  }

  @OnLifecycleEvent (Lifecycle.Event.ON_DESTROY)
  fun tearDown() {
    Log.i (TAG, "Destroying background thread")
  }
}

当我启动我的程序时,我有以下日志:

I/ThumbnailDownloader: Starting background thread
I/ThumbnailDownloader: Got a url: https://live.staticflickr.com/65535/51311768062_a2d5c73f65_m.jpg
...
I/ThumbnailDownloader: Got a url: https://live.staticflickr.com/65535/51312058978_199964de5a_m.jpg

但我计划有另一个日志:

I/ThumbnailDownloader: Starting background thread
I/ThumbnailDownloader: Got a url: https://live.staticflickr.com/65535/51311768062_a2d5c73f65_m.jpg
I/ThumbnailDownloader: Got a request for URL: https://live.staticflickr.com/65535/51311768062_a2d5c73f65_m.jpg
...
I/ThumbnailDownloader: Got a url: https://live.staticflickr.com/65535/51312058978_199964de5a_m.jpg
I/ThumbnailDownloader: Got a request for URL: https://live.staticflickr.com/65535/51312058978_199964de5a_m.jpg

override fun handleMessage(msg: Message)不执行的代码。也许这是因为 line requestHandler = Handler(),其中 Handler() 被划掉,Android Studio 告诉它已被弃用。

我需要做什么来运行 handleMessage 代码?也许我需要在后台线程中对 Looper 做一些事情,我不知道。感谢您的回答!

4

1 回答 1

0

我忘记了:

  1. 将 looper 添加到我的Handler()构造函数中onLooperPrepared()
  2. 添加start()fun setup()_ quit()_fun tearDown()
  3. 并且代码行requestHandler = Handler()过多。

在我看了一部简单解释 HandlerThread、Handler 和 Looper 发生了什么的小电影后,我猜到了这一切。

问题已关闭。

于 2021-07-16T18:52:50.180 回答