河北网站seo策划威海团购网站建设

当前位置: 首页 > news >正文

河北网站seo策划,威海团购网站建设,wordpress更新提示,吉林省公共资源交易信息网详解 Handler 机制 1、Handler 的引出场景2、主要组件2.1、Handler2.2、Message2.3、MessageQueue2.4、Looper2.5、组件之间的关系 3、工作原理及代码示例3.1、工作机制3.2、代码示例3.2.1、使用 Handler.sendMessage() 发送消息3.2.2、使用 Handler.post() 发送消息 1、Handle… 详解 Handler 机制 1、Handler 的引出场景2、主要组件2.1、Handler2.2、Message2.3、MessageQueue2.4、Looper2.5、组件之间的关系 3、工作原理及代码示例3.1、工作机制3.2、代码示例3.2.1、使用 Handler.sendMessage() 发送消息3.2.2、使用 Handler.post() 发送消息 1、Handler 的引出场景 有这样一个场景需要在一个页面上倒计时5秒然后跳转到另一个页面。如下图所示 我们容易想到可以在子线程里倒计时五秒倒计时结束后去跳转即可。 代码如下 activity_main.xml ?xml version1.0 encodingutf-8? LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:orientationverticalandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentTextViewandroid:idid/textViewandroid:gravitycenterandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:textSize30sp //LinearLayoutMainActivity.kt package com.example.handlertestimport android.content.Intent import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.example.handlertest.databinding.ActivityMainBindingclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val binding ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)//开启子线程Thread {for (i in 5 downTo 1) {binding.textView.text i.toString()try {Thread.sleep(1000)} catch (e: InterruptedException) {e.printStackTrace()}}// 计时结束后跳转到新页面val intent Intent(this, MainActivity2::class.java)startActivity(intent)}.start()} }但是运行的时候你会发现这段代码大概率会报错之所以不百分百报错是因为早期版本的Android中或是特定情况下可能会容忍这种行为而不立即抛出异常。但是直接在非UI线程中更新UI组件的行为违反了Android的多线程规则。根据 Android 文档所有的 View 操作都应该在主线程 UI 线程中执行。这是因为 Android 的 View 系统不是线程安全的如果尝试在非 UI 线程中直接更新 UI理论上会触发一个 CalledFromWrongThreadException 异常从而导致应用程序的崩溃或异常行为。 这种在子线程中处理某些操作并需要在主线程中同步更新 UI 界面的Android 为我们提供了一套异步消息处理机制Handler。 2、主要组件 Handler 机制的实现主要依靠以下四个组件 2.1、Handler Handler 是用于发送和处理消息的工具。它提供了将任务从一个线程传递到另一个线程的机制通常用于将任务从子线程传递到主线程。 发送消息Handler 可以通过 sendMessage、post 等方法将消息或任务发送到目标线程的消息队列中。处理消息Handler 通过重写 handleMessage 方法来处理接收到的消息。 2.2、Message Message 是用于在不同线程之间传递数据的载体。它包含了消息的标识符、数据和目标 Handler。 字段 what消息的标识符用于区分不同类型的消息。arg1 和 arg2整型数据可以用于传递简单的数据。obj对象数据可以用于传递复杂的数据。target目标 Handler用于处理消息。 2.3、MessageQueue MessageQueue 是一个 FIFO先进先出的消息队列用于存储从 Handler 发送的消息。每个线程都有一个唯一的 MessageQueue。 入队消息通过 Handler 被添加到 MessageQueue 中。出队Looper 从 MessageQueue 中取出消息并将其分发给目标 Handler 进行处理。 2.4、Looper Looper 是一个用于循环处理消息队列中消息的工具。每个线程只有一个 Looper主线程默认已经有一个 Looper可以直接拿来使用。其它线程需要自行创建后才可使用。 准备 主线程默认已经有了也可以通过 Looper.prepareMainLooper() 方法手动创建不推荐子线程通过 Looper.prepare() 方法为当前子线程创建一个 Looper。 循环通过 Looper.loop() 方法开始循环处理消息队列MessageQueue中的消息。获取 Looper.getMainLooper()获取主线程的 LooperContextWrapper 对象的 getMainLooper()获取主线程的 LooperLooper.myLooper()获取当前线程的 Looper。
2.5、组件之间的关系 一个线程只有一个 MessageQueue 和 一个 Looper一个线程可以绑定多个 Handler一个 Handler 只能绑定一个 Looper一个 Looper 可以绑定多个 Handler 3、工作原理及代码示例 3.1、工作机制 创建 Handler在目标线程中创建一个 Handler 实例。发送消息通过 Handler 的 sendMessage 或 post 方法将消息或任务发送到目标线程的 MessageQueue 中。消息入队消息被添加到目标线程的 MessageQueue 中。Looper 处理消息目标线程的 Looper 不断从 MessageQueue 中取出消息并将其分发给对应的 Handler。Handler 处理消息Handler 的 handleMessage 方法被调用处理接收到的消息。 通过这种机制Android 实现了线程间的通信和任务调度确保 UI 操作在主线程中执行从而避免线程安全问题。 3.2、代码示例 activity_main.xml 中的代码不变只有一个简单的 TextView 组件。下面将展示在 MainActivity.kt 中分别使用 Handler.sendMessage() 方法和 Handler.post() 方法实现本文开头所提的场景。 3.2.1、使用 Handler.sendMessage() 发送消息 package com.example.handlertestimport android.content.Intent import android.os.Bundle import android.os.Message import androidx.appcompat.app.AppCompatActivity import com.example.handlertest.databinding.ActivityMainBinding import android.os.Handlerclass MainActivity : AppCompatActivity() {private lateinit var handler: Handleroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val binding ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)// 在主线程中创建 handler并绑定主线程的 Looperhandler object : Handler(mainLooper) {// 重写 handleMessage() 方法编写消息处理逻辑override fun handleMessage(msg: Message) {super.handleMessage(msg)when (msg.what) {1 - {binding.textView.text msg.arg1.toString()}2 - {val intent Intent(thisMainActivity, MainActivity2::class.java)startActivity(intent)}}}}// 开启子线程Thread {for (i in 5 downTo 1) {val msg Message.obtain(handler, 1)msg.arg1 i// 通过 sendMessage() 发送消息handler.sendMessage(msg)try {Thread.sleep(1000)} catch (e: InterruptedException) {e.printStackTrace()}}val msg Message.obtain(handler, 2)// 通过 sendMessage() 发送消息handler.sendMessage(msg)}.start()} }3.2.2、使用 Handler.post() 发送消息 package com.example.handlertestimport android.content.Intent import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.example.handlertest.databinding.ActivityMainBinding import android.os.Handlerclass MainActivity : AppCompatActivity() {private lateinit var handler: Handleroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val binding ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)// 在主线程中创建 handler并绑定主线程的 Looperhandler Handler(mainLooper)// 开启子线程Thread {for (i in 5 downTo 1) {// 通过 post() 发送消息需要传入一个 Runnable 对象在 Runnable 的 run() 方法中指定 UI 操作内容// 此处使用了 lambda 表达式handler.post { binding.textView.text i.toString() }try {Thread.sleep(1000)} catch (e: InterruptedException) {e.printStackTrace()}}// 通过 post() 发送消息handler.post {val intent Intent(thisMainActivity, MainActivity2::class.java)startActivity(intent)}}.start()} }