1.线程概述
线程是进程的一部分,是执行程序的最小单元。计算机处理代码是按照顺序执行的,如果全部在一个线程中执行代码,就必须等前面的任务执行完,才执行后面的任务。在android系统中一个程序只有一个主线程,即UI线程,这个线程是程序运行时系统创建的,负责处理用户界面的更新和事件响应,所以我们只能创建多个子线程去完成耗时任务
2.线程创建和管理
2.1继承 Thread 类
通过继承Thread类并重写run()创建新的线程
class MyThread extends Thread{
@Override
public void run(){
//在这里执行耗时操作
}
}
2.2实现 Runnable 接口
创建一个实现Runnable接口的类,并将其作为参数传递给Thread类的构造方法
class MyRunnable implements Runnable{
@Override
public void run(){
//在这里执行耗时操作
}
}
2.3使用 AsyncTask 类
通过继承 AsyncTask 类并重写其方法来创建子线程。
public class MyAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
// 子线程要执行的代码
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
// UI 操作
}
}
2.4使用Executors创建
// 使用 Executor 框架
//固定线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
//缓存线程池
ExecutorService executor =Executors.newCachedThreadPool();
//顺序线程池
ExecutorService executor =Executors.newSingleThreadExecutor();
周期定时线程池
ExecutorService executor =Executors.newScheduledThreadPool(5);
//execute和submit区别
//execute只能提交Runnable任务,没有返回值,execute的异常是直接抛出的
//submit能提交Runnable和Callable任务,返回Future类型。
//submit方法是捕获了异常的,当调用FutureTask的get方法时,才会抛出异常
//executor.execute(new MyRunnable());
executor.submit(new MyRunnable());
//关闭线程池
executor.shutdown();
FixedThreadPool固定线程池
CachedThreadPool缓存线程池
SingleThreadExecutor按顺序执行线程池
ScheduledThreadPool定时周期任务线程池
3.线程中常见的类和接口
Thread:线程类,用于创建和管理线程。
Runnable:线程接口,定义了线程的执行代码。
Handler:用于在不同线程之间传递消息和执行操作。
AsyncTask:简化异步任务处理的工具类。
Executor:线程池的抽象接口,用于管理线程的执行。
Future:表示异步任务的结果,可以通过它来获取任务的执行状态和结果。
4.线程间的通信方式
Handler
用于在不同线程之间传递消息和执行操作。将消息发送到主线程来更新 UI,或者在工作线程中执行后台任务。
AsyncTask
简化异步任务处理的工具类。它提供了在后台线程执行任务并在主线程更新 UI 的便利方法。
BroadCastReceiver
BroadcastReceiver 是 Android 中用于接收广播消息的组件,可以在不同线程之间传递消息和执行操作。
线程同步机制
通过使用 synchronized 关键字、Lock、Condition 等线程同步机制,可以实现线程间的协调和通信。
EventBus
EventBus是一个开源的事件总线库,可以用于不同组件之间的通信。可以在一个线程中发布事件,然后在另一个线程中订阅并处理事件。
5.RxJava对线程的使用
RxJava 是一种响应式编程,来创建基于事件的异步操作库。常用于流时间的处理和配合Retrofit进行异步请求和线程切换,线程切换的关键代码:
.subscribeOn(Schedulers.io()) //切换到子线程
.observeOn(AndroidSchedulers.mainThread())//切换到UI线程
6.kotlin协程对线程的处理
协程本质上是依赖线程,通过调用系统资源来处理任务,协程的主要任务就是协助线程,是线程的助手,分担线程的任务。
7.总结
在Java环境中,简单的异步处理可以直接new Thread,需要进度的或者下载的用AsyncTask,需要频繁切换线程或者和网络请求配合的可以用rxjava。kotlin协程包含了线程的功能,也包含了RxJava事件流的能力,可以用于处理异步操作