技术日记----2020.9.7

本文深入探讨安卓中线程与Handler的工作原理,解析主线程与异步线程的管理,以及如何使用Handler进行线程间的消息传递和任务调度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有一定操作系统基础知识的同学都知道,线程可以称为轻量的进程,具有极其有限的一部分独立空间,能够独立执行一定的任务,但是创建销毁的空间时间资源都要远低于进程。

 

在安卓中,一般来说一个app运行在一个进程之上(暂时不考虑native方法fork出的子进程),而进入这个进程我们最先接触到的线程就是UI线程(主线程)。主线程负责向UI组件分发事件,包括绘制点击等,这个线程资源很稀缺,一旦进行了过多的耗时操作就可能出现anr。

 

我们都知道在cpu层面,所有的线程都是在cpu上按照一个一个时间片执行的,一个时间片可能会有数个毫秒。当然线程之间会有不同的优先级和调度方式,但是线程过多导致的切换花销也是没必要的。比如只是进行一个简单的网络请求或者加载资源,完全没必要单独创建一个线程。这里就可以使用线程池或者自定义一个线程进行处理,这个线程或者几个线程可以长期存活(也相当于自定义线程池)。

当然线程池的在整个大型的app项目中使用比较繁琐,而不断的new Thread又很耗费资源,这里就搬出我们强大的handler。

从我们开发者的角度来说,Handler是Android消息机制的上层接口,通过handler,可以将一个任务切换到handler所在的线程中执行,我们通常使用handler来更新UI,但更新UI仅仅是的使用场景之一,handler并不是仅仅用来更新UI。它也可以运行在异步线程上,执行耗时的任务。

至于handler的具体使用和机制这里就不具体讲解了各种文章有很多。

这里我们需要澄清一个容易绕晕的概念,在安卓中,每个线程都会持有一个looper,负责从消息队列中取出消息进行执行。一个线程只能有一个looper,但是一个looper可以服务于多个线程。也就是线程本身的looper负责从自己的任务队列中取出任务进行执行,mainlopper持有者即为主线程,可以通过

Looper.myLooper() == Looper.getMainLooper()

判断当前是否在主线程

我们就可以在主线程创建一个handler,构造方法中传入mainlopper,在handleMessage前判断

if (Looper.myLooper() != Looper.getMainLooper()) {
    return;
}

那么抛到这个handler执行的任务都会在主线程进行。

 

那么异步线程也是同理的

自定义一个子线程,在线程run的时候

 Looper.prepare();
 // 定义handler等操作
 Looper.loop();

我们的线程handler就有了自己的looper,即运行在异步线程上。而抛到这里的代码块都会执行在异步线程上,一些费时的操作都可以在这里执行,包括后台加载资源等。

 

这样一个单例类就可以管理主线程和异步线程,并且很方便的进行线程的切换和管理。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值