同步:在发生某件事后什么也不做,直到该事件完成后,再继续进行
异步:在某件事发生后,可以在等待他完成的时候去处理其他事件,等到该事件发生完成后,再回过头来处理它。
异步操作的核心思想就是将耗时操作放到子线程中执行,避免阻塞主线程,从而保持界面的流畅性。
Android 提供了 Handler 机制来进行线程之间的通信,我们可以使用 Android 最基础的异步方式:Thread + Looper + handler 来进行异步任务
- Handler mHandler = newHandler(){
- @Override
- publicvoid handleMessage(Message msg){
- if(msg.what == 1){
- textView.setText("Task Done!!");
- }
- }
- };
- mRunnable = new Runnable() {
- @Override
- publicvoid run() {
- SystemClock.sleep(1000); // 耗时处理
- mHandler.sendEmptyMessage(1);
- }
- };
- private void startTask(){
- new Thread(mRunnable).start();
- }
AsyncTask是较为轻量级的异步类,封装了 FutureTask 的线程池、ArrayDeque 和 Handler 进行调度。AsyncTask 主要用于后台与界面持续交互。
当我们定义一个类来继承 AsyncTask 这个类的时候,我们需要为其指定3个泛型参数:
AsyncTask
- Params: 这个泛型指定的是我们传递给异步任务执行时的参数的类型。
- Progress: 这个泛型指定的是我们的异步任务在执行的时候将执行的进度返回给UI线程的参数的类型。
- Result: 这个泛型指定的异步任务执行完后返回给UI线程的结果的类型。
- 我们在定义一个类继承 AsyncTask 类的时候,必须要指定好这三个泛型的类型,如果都不指定的话,则都将其写成 void。
结构清晰,使用简单,适合后台任务的交互。
异步线程的优先级已经被默认设置成了:THREAD_PRIORITY_BACKGROUND,不会与 UI 线程抢占资源。
结构略复杂,代码较多。
每个 AsyncTask 只能被执行一次,多次调用会发生异常。
AsyncTask 在整个 Android 系统中维护一个线程池,有可能被其他进程的任务抢占而降低效率。
利用 Executors 的静态方法 newCachedThreadPool()、newFixedThreadPool()、newSingleThreadExecutor() 及重载形式实例化 ExecutorService 接口即得到线程池对象。
下面代码中,新建了一个固定数量为4的线程池
- @Database(entities = {AccountDataItem.class, AccountData.class},version = 6,exportSchema = false)
- public abstract class AppRoomDataBase extends RoomDatabase {
- private static volatile AppRoomDataBase INSTANCE;
- public abstract AccountDao accountDao();
- public abstract AccountListDao accountListDao();
-
- public static final ExecutorService databaseWriteExecutor = Executors.newFixedThreadPool(4);
- // 单例模式
- public static AppRoomDataBase getDataBase(Context context){
- if (INSTANCE == null) {
- synchronized (AppRoomDataBase.class) {
- if (INSTANCE == null) {
- INSTANCE = Room.databaseBuilder(
- context.getApplicationContext(),
- AppRoomDataBase.class,
- "记账数据库"
- )
- .fallbackToDestructiveMigration()
- .build();
- }
- }
- }
- return INSTANCE;
- }
- }
- public void deleteAllAccountItem() {
- appRoomDataBase.databaseWriteExecutor.execute(() -> accountDao.deleteAll());
- }