IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 多多色Android系统编程入门系列色彩多多服务Service齐头线程任务 -> 正文阅读

[移动开发]多多色Android系统编程入门系列色彩多多服务Service齐头线程任务

什么是线程呢?每个应用程序在初始化时,默认运行在以其包名命名的进程中,同一进程中的内存是可以共享使用的。而每个进程在创建时,都会随之创建一个java.lang.Thread实例的线程,用以执行Android系统对当前应用程序的生命周期方法回调,也就是通常意义上的UI界面绘制等任务,这也就是所谓的主线程。而每个进程在主线程中,可以继续创建多个线程,理论上只要硬件内存支持,线程是可以无限创建的。这些新创建的线程,被称为子线程。子线程中可以执行耗时任务,以此使得主线程中的界面任务保持与用户的及时响应。
值得注意的是,子线程中是不允许执行更新界面相关操作,必须切换回主线程绘制界面。

任务创建
新任务类需要实现java.lang.Runnable接口,在实现的run()方法中处理需要操作的任务。

任务执行
在开发中启动新任务的方式主要有三种,其一是直接创建最基础的线程类,单独管理并执行耗时任务;其二是创建一个由一堆线程组成的线程池,将耗时任务放进去执行,剩下的由线程池管理;其三则是使用成熟的并发库,根据不同的并发库创建及启动任务的方式也将不仅限于Runnable类型的实例。另外在Android R即API30以前,还可以使用android.os.AsyncTask创建异步任务,但是该方式在API30之后已废弃,故不推荐使用。下面将简单介绍以上三种主流方式。

单独线程
通常使用Thread(Runnable target)构造方法创建子线程,参数 target 作为要执行的任务对象。
之后在需要执行任务的位置调用子线程对象的start()方法启动运行该线程即可。
由于创建的线程是依托于某个界面Activity或服务Service的一个组件,所以当该组件的生命周期方法销毁后,其中创建的子线程也就销毁了。所以子线程必须要在被销毁之前调用interrupt()方法中断运行并释放其占用的资源,以防止发生内存泄漏等问题。

线程池
通过线程池管理类java.util.concurrent.Executors的newCachedThreadPool()等系列静态方法,可以直接创建java.util.concurrent.Executor接口定义的线程池类实例化对象。
之后在需要执行任务的位置调用线程池对象的execute(Runnable command)方法即可执行一次任务。
线程池类的优点在于当该组件的生命周期方法销毁后,该线程池及其中的线程都会被强制销毁,不需要手动管理。

并发库
关于Android系统的多线程开发,目前已有多个成熟的并发库可以直接使用,包括基于Java的RxJava、基于Kotlin的协程等,然而他们的底层原理都是与上述类似的。至于如何使用现有的多线程开发库,将在后续文章中详细介绍。

任务间通信(多线程通信)
由于不同任务是运行在不同线程中的,所以任务间通信实际上也是线程间的通信。这主要通过android.os.Handler类来实现的。说到通信的话就是一方发送内容和另一方接收内容的过程,Android系统将要通信的内容封装为android.os.Message类,其中有 int arg1和int arg2两个属性储存简单的数值内容、Object obj属性存储任意类型的对象、int what属性可以标记区分不同的Message类型。

通信接收线程
在需要处理通信内容的线程中,创建Handler实例化对象。
可以使用Handler(Looper looper)构造方法或者createAsync(Looper looper)静态方法,创建处理任意内容的实例化对象。其中的参数 looper 标记当前Handler对象中的处理操作是在哪个线程,如果是主线程可以使用Looper.getMainLooper()静态方法获取android.os.Looper对象,如果是子线程,可以在子线程的run()方法中使用Looper.myLooper()静态方法获取当前线程的Looper对象。

或者使用Handler(Looper looper, Handler.Callback callback)构造方法或者createAsync(Looper looper, Handler.Callback callback)静态方法,创建需要接收Message消息处理的实例化对象。参数 looper 同样是标记当前Handler对象中的处理操作是在哪个线程。参数 callback 是android.os.Handler.Callback接口实现的实例化对象,其中实现的handleMessage(Message msg)方法可以接收并处理通信的结果。这里的参数 msg 就是收到的Message消息内容。

如果是通过Looper.myLooper()静态方法获取的Looper对象,也就是在子线程中处理通信结果的话,在创建Handler对象前后还要特别调用两个方法。
在上面初始化Handler对象之前,必须在子线程中先调用Looper.prepare()静态方法以初始化Looper对象,以此保证在调用Looper.myLooper()方法时获取到的对象非空。
以及在初始化Handler对象之后,必须在当前子线程中及时调用Looper.loop()静态方法以准备Message消息队列供当前子线程使用。

通信发送线程
在需要发送通信内容的线程中,需要首先接收到上文创建的Handler实例化对象。

在切换线程处理的位置,调用Handler对象的post(Runnable r)系列方法,参数 r 就是要在Handler对象所在线程中处理的Runnable任务对象。

或者在需要发送消息的位置,调用Handler对象的obtainMessage()系列方法,可以获取到空闲可以使用的Message消息对象,将要发送的消息体内容赋值给Message对象的不同属性。最后再调用Handler对象的sendMessage(Message msg)系列方法,将消息体Message对象发送即可。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-15 15:43:16  更:2021-08-15 15:44:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 11:07:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码