使用从 HandlerThread 继承的类时,Handler/Looper 出现问题,handleMessage 的代码不运行

如何解决使用从 HandlerThread 继承的类时,Handler/Looper 出现问题,handleMessage 的代码不运行

我的项目中有一个片段:

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)代码未执行。 也许这是因为行requestHandler = Handler(),其中 Handler() 被划掉了, Android Studio 表示已弃用。

我需要做什么来运行 handleMessage 代码?也许我需要用 Looper 做点什么 后台线程,我不知道。感谢您的回答!

解决方法

我忘记了:

  1. 将looper添加到{ token: { kind: "identitytoolkit#VerifyPasswordResponse",email: "myEmail@gmail.com",displayName: "myName",idToken: "generatedToken",registered: true },message: "successfully created user profile" } 中的Handler()构造函数
  2. onLooperPrepared()中添加start(),在fun setup()中添加quit()
  3. 并且代码行 fun tearDown() 过多。

我看了一部简单解释了 HandlerThread、Handler 和 Looper 的小电影后就猜到了这一切。

问题已解决。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?