首页 > 其他分享 >Android笔记【7】

Android笔记【7】

时间:2024-11-22 20:17:39浏览次数:3  
标签:value imageId Handler 线程 笔记 图像 Message Android

一、前言

        学习课程时,对于自己不懂的点的记录。

二、内容

学习(十二)结合Compose实现Handler机制处理多线程的通信。

效果图:

学习片段一:

这段代码是使用 Kotlin 编写的 Android Handler 的一个示例。下面是对代码的详细介绍:

val handler = object : Handler(Looper.getMainLooper()) {
    override fun handleMessage(msg: Message) {
        super.handleMessage(msg)
        if (msg.what == 0x123) {
            // 接受数据,并修改状态值
            imageState.value = msg.arg1
        }
    }
}

1、定义Handler对象

关键部分说明

  1. Handler:

    • Handler 是 Android 中用于处理消息和执行操作的工具。它可以用来在特定的线程中执行代码,通常是主线程(UI线程)。
  2. Looper.getMainLooper():

    • Looper 是一个消息循环的类,getMainLooper() 返回主线程的消息循环。创建 Handler 时传入这个 Looper,可以确保 handleMessage 方法在主线程中执行。
  3. 重写 handleMessage 方法:

    • handleMessage 方法用于接收和处理发送到该 Handler 的消息。
    • 使用 super.handleMessage(msg) 调用父类的实现,确保父类的处理逻辑也能执行。
  4. 消息处理:

    • 代码中检查 msg.what 是否等于 0x123,这是一个自定义的消息标识符。
    • 如果条件满足,代码将 msg.arg1 的值赋给 imageState.value,这通常用于更新 UI 状态或数据。

用途

这种模式常用于在后台线程(例如网络请求或长时间运行的任务)完成后,向主线程发送消息以更新 UI。例如,当下载图片或获取数据时,可以使用此 Handler 来更新显示状态。

总结

这段代码展示了如何在 Android 开发中使用 Handler 来处理消息和更新状态,确保这些操作在主线程中执行,以避免潜在的线程安全问题。

2、msg: Message 这里的Message是什么?

在 Android 中,Messageandroid.os.Message 类的一个实例,用于在 Handler 和其他组件之间传递数据。它通常用于异步通信,允许不同线程之间进行消息传递。

Message 的主要特性

  1. 消息标识:

    • 每个 Message 有一个 what 字段,通常用于标识消息类型或类别。开发者可以自定义此字段以便于识别和处理不同类型的消息。
  2. 附加数据:

    • Message 还包含一些额外的字段,如:
      • arg1arg2: 这两个字段通常用于存储整数数据,可以用于传递额外的信息或状态。
      • obj: 这个字段可以存储一个任意的对象,允许在消息中传递更复杂的数据。
      • data: 这是一个 Bundle 对象,可以用于传递键值对形式的额外数据。
  3. 发送和处理:

    • Message 可以通过 HandlersendMessage 方法发送。在目标 HandlerhandleMessage 方法中,可以接收并处理这些消息。

使用示例

以下是一个简单的示例,展示如何创建和发送 Message

val message = Message.obtain()
message.what = 0x123
message.arg1 = 42 // 传递一个整数
handler.sendMessage(message)

在上面的代码中,创建了一个新的 Message 实例,设置了 whatarg1 字段,然后通过 handler.sendMessage(message) 发送到关联的 Handler,在对应的 handleMessage 方法中将会处理这个消息。

总结

Message 类在 Android 中是一个强大的工具,允许你在不同线程之间异步传递信息,非常适合用于 UI 更新或后台任务的结果处理。

3、定义图片仓库

val imageRepository = ImageRepository(handler)

学习片段二

提供的 requestImage 函数中,有几个关键部分相互关联,主要是关于如何在后台线程中处理图像请求并通过 Handler 将结果发送回主线程。以下是对这段代码的详细解析:

fun requestImage(imageId: MutableState<Int>) {
    thread {
        // 定义工作线程
        while (imageId.value in 0 until imageList.size) {
            Thread.sleep(1000)
            var message = Message.obtain()
            message.what = 0x123
            message.arg1 = imageList[imageId.value]
            imageId.value = imageId.value + 1
            // 发送数据
            handler.sendMessage(message)
        }
    }
}

关键部分分析

  1. 后台线程:

    • thread { ... } 创建了一个新的线程来执行其中的代码。这是为了确保耗时的操作(如图像请求)不会阻塞主线程(UI线程)。
  2. 循环处理:

    • while (imageId.value in 0 until imageList.size) 这个循环会持续运行,直到 imageId.value 超过 imageList 的大小。这样可以确保只处理有效的图像 ID。
  3. 延迟处理:

    • Thread.sleep(1000) 让线程暂停 1 秒,模拟一个下载或处理图像的过程。这种方式常用于测试或模拟延迟。
  4. 创建和填充 Message:

    • Message.obtain() 创建一个新的 Message 实例。
    • message.what = 0x123 设置消息的类型,通常用于识别消息。
    • message.arg1 = imageList[imageId.value] 将当前图像的 ID 或数据存储在 arg1 字段中。
  5. 更新 imageId:

    • imageId.value = imageId.value + 1 增加 imageId 的值,以便在下一个循环中处理下一个图像。
  6. 发送消息:

    • handler.sendMessage(message) 将创建的 Message 发送到与 Handler 相关联的线程(通常是主线程)。这使得可以在主线程中处理图像数据并更新 UI。

联系和作用

  • Handler 的作用:
    Handler 在这里的作用是接收来自后台线程的消息并在主线程中处理这些消息。这种设计模式确保了 UI 更新是线程安全的,因为 Android 的 UI 操作只能在主线程中执行。

  • MutableState<Int> 的作用:
    imageId 是一个可变状态,通常用于在 Compose 等框架中跟踪状态变化。它的值会在每次循环中更新,以便指向当前处理的图像。

总结

在这段代码中,requestImage 函数的设计通过使用 Handler 和后台线程,成功地将耗时的图像请求与 UI 更新逻辑分离。Handler 负责将处理结果发送回主线程,而 MutableState<Int> 用于跟踪当前正在处理的图像 ID,使得整个过程既高效又线程安全。

4、painterResource

Image(painter=painterResource(imageState.value),contentDescription="image")
中,painter参数介绍,还有painterResource解释介绍。

1. painter 参数

  • 定义:

    • painterImage 组件的一个参数,类型为 Painter。它用于定义如何绘制图像。
  • 作用:

    • painter 可以是从不同来源创建的,例如从资源文件、网络、内存缓存等。它抽象了图像的绘制逻辑,使得在 Compose 中使用图像变得简单而灵活。

2. painterResource 函数

  • 定义:

    • painterResource 是一个用于加载图像资源的函数。它接受一个资源 ID,并返回一个 Painter 对象,以便在 Image 组件中使用。
  • 用法:

    • 你可以通过 painterResource 从 drawable 资源中加载图像。例如:
    val painter = painterResource(id = R.drawable.my_image)
    
  • 完整代码示例:

    @Composable
    fun MyImageComponent(imageResId: Int) {
        Image(
            painter = painterResource(imageResId),
            contentDescription = "image"
        )
    }
    

结合使用

在你的代码中,Image(painter = painterResource(imageState.value), contentDescription = "image") 的含义如下:

  • imageState.value 应该是一个包含图像资源 ID 的状态值(例如 R.drawable.my_image)。
  • painterResource(imageState.value) 通过传入图像的资源 ID,加载相应的图像,并返回一个 Painter 对象。
  • Image 组件使用这个 Painter 来绘制图像,并通过 contentDescription 提供图像的描述,提升可访问性。

总结

  • painterImage 组件的一个参数,用于指定图像的绘制方式。
  • painterResource 是一个函数,用于从资源中加载图像返回一个 Painter 对象,以便可以在 Compose 中使用。通过这种方式,你可以轻松地将资源图像显示在 UI 中。

5、 MutableState<Int> 类型

在 Jetpack Compose 中,currentSelected 是一个 MutableState<Int> 类型的状态对象。它用于管理和观察与 UI 相关的状态变化。理解何时使用 .value 以及何时直接传递参数的关键在于状态的处理方式。

1. MutableState 的结构

  • MutableState<Int>:
    • currentSelected 是一个可变状态,它的值可以被修改并且可以在 UI 中观察。
    • currentSelected.value 是获取这个状态的实际整数值。

2. 使用 .value 的情况

  • 获取状态值:

    • 当你需要使用 currentSelected 的实际整数值时,需要通过 .value 来访问。例如,在 RadioButtonselected 属性中:

      selected = currentSelected.value - 1 == i
      
    • 在这里,.value 用于获取当前选择的索引,以便与循环中的 i 进行比较。

  • 设置状态值:

    • 当你需要更新 currentSelected 的值时,也需要通过 .value 来进行赋值。例如,在 onClick 事件中:

      onClick = {
          currentSelected.value = i
      }
      
    • 这里,.value 被用来将 currentSelected 的值更新为 i

3. 直接传参的情况

  • 直接传递 MutableState 对象:
    • 在某些情况下,如果函数的参数能够接受 MutableState 对象,你可以直接传递该对象,而不需要访问 .value。例如,在调用 imageRepository.requestImage 方法时,如果该方法的参数是 MutableState<Int> 类型:

      Button(onClick = {
          imageRepository.requestImage(currentSelected)
      })
      
    • 在这个例子中,requestImage 方法可能需要整个 MutableState 对象,以便在其内部访问和修改值。你可以直接传递 currentSelected,而不需要使用 .value

总结

  • 使用 .value 是在需要获取或设置 MutableState 的实际值时。
  • 当你直接传递 MutableState 对象本身时,不需要使用 .value,因为函数可以直接处理状态对象。
  • 理解这两者之间的区别可以帮助你更有效地管理 Compose 中的状态。

6、附上源代码

(为了简便放一个txt文件里了,加上图片也是可以运行的)

通过百度网盘分享的文件:cy(csdn十二)handler多线程.zip
链接:https://pan.baidu.com/s/1uA6qPHRDrT303SLKJjOCxw?pwd=wune 
提取码:wune 
--来自百度网盘超级会员V1的分享

标签:value,imageId,Handler,线程,笔记,图像,Message,Android
From: https://blog.csdn.net/m0_72696598/article/details/143975844

相关文章

  • Android笔记【8】
    一、前言    学习课程时,对于自己不懂的点的记录。二、内容学习(二十四)基于Compose组件的MVVM模式和MVI模式的实现1、collectAsState()在JetpackCompose中,collectAsState()是一个用于将KotlinFlow数据流转换为Compose状态的扩展函数。通过使用collectAsSt......
  • rk3568 android11 从frameworks添加服务到 android studio app应用
    1.在frameworks下添加,其目录如下:1.1添加IDemoManager.aidl文件//mls_demo//IDemoManager.aidlpackageandroid.app;//Declareanynon-defaulttypesherewithimportstatementsinterfaceIDemoManager{  intplus(inta,intb);} 1.2添加DemoManag......
  • android开发中,button设置shape后,shape的颜色不生效的问题解决方案
    检查AndroidManifest.xml中的主题的属性<applicationandroid:name=".BaseApplication"android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:networkSecurityConf......
  • 泷羽Sec学习笔记:shell(2)永久环境变量和字符串显位
    学习笔记:shell编程(2)永久环境变量和字符串显位_哔哩哔哩_bilibili永久变量:echo$PATH 查看环境变量echo$HOME  家目录root用户我们使用的ls、dir命令能输出内容就是因为这些命令都有相对应的变量。which--als  查看ls命令的脚本路径查看echo$PATH:/usr/l......
  • css笔记: 继承关系
    这两天写css的时候发现子元素继承了父元素的css样式,不显示它自己的。经过一番搜索,得出以下几个解决方案:检查选择器优先级增加样式的特异性避免不必要的继承使用!important标记(谨慎使用)检查CSS规则的顺序明确样式规则,减少对父元素的依赖考虑使用CSS变量理解CSS的层叠规则......
  • Android MQTT的使用以及一些常见的问题
    1.AndroidMQTT使用步骤引入依赖先连接订阅发布取消订阅取消连接首先,确保你的AndroidManifest.xml文件中声明了这些权限<uses-permissionandroid:name="android.permission.INTERNET"/><uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW"/......
  • Allegro学习笔记( 四)如何一次性添加GND过孔
    PCB周围添加地孔的好处:一是有效减少PCB边缘上电磁波的辐射和传播,减少PCB对外围设置的信号干扰,提高PCB的抗干扰能力;二是减小PCB板边的翘曲的变形。那么问题就来了,那么多过孔需要手动一个个添加,那得是多么繁琐的工作,还需要保持PCB的美观,那更是难上加难了。小编给大家介绍一种......
  • [学习笔记 #5] 哈希
    目录[学习笔记#5]哈希前言哈希表过渡:用哈希解决判定性问题不知道归到哪里去的技巧集合哈希SumHashingXorHashing序列哈希树哈希数据结构维护哈希值参考[学习笔记#5]哈希下面[]起来的是我还不确定的。前言从今年暑假到现在(2024.11.13),考了多少道哈希,我一道都没场切。前......
  • C高级学习笔记
    ……接上文shell中的语句功能性语句testtest语句可以测试三种对象:字符串整数文件属性每种测试对象都有若干测试操作符3.1.字符串测试s1=s2测试两个字符串的内容是否完全一样test"hello"="world"echo$?#1相等为真,不想等为假s1!=s2......
  • .Net-Avalonia学习笔记(十)-Material.Avalonia
     Add Material.Avalonia nugetpackagetoyourproject:dotnetaddpackageMaterial.AvaloniaEdit App.xaml file:<Application...xmlns:themes="clr-namespace:Material.Styles.Themes;assembly=Material.Styles"...><Application......