Java 无法访问主线程上的数据库,因为它可能会长时间锁定UI错误

Java 无法访问主线程上的数据库,因为它可能会长时间锁定UI错误,java,android,compiler-errors,android-room,illegalstateexception,Java,Android,Compiler Errors,Android Room,Illegalstateexception,每当我想启动“NotenActivity”时,它都会显示以下错误: Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. at androidx.room.RoomDatabase.assertNotMainThread(RoomDa

每当我想启动“NotenActivity”时,它都会显示以下错误:

  Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
        at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:209)
        at androidx.room.RoomDatabase.query(RoomDatabase.java:237)
        at com.example.mykolproject.persistance.dao.NoteDao_Impl.getnAll(NoteDao_Impl.java:121)
        at com.example.mykolproject.NoteRepository.<init>(NoteRepository.java:23)
        at com.example.mykolproject.NoteViewModel.<init>(NoteViewModel.java:20)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343) 
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103) 
        at com.example.mykolproject.NotenActivity.onCreate(NotenActivity.java:130) 
        at android.app.Activity.performCreate(Activity.java:7458) 
        at android.app.Activity.performCreate(Activity.java:7448) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199) 
        at android.os.Handler.dispatchMessage(Handler.java:112) 
        at android.os.Looper.loop(Looper.java:216) 
        at android.app.ActivityThread.main(ActivityThread.java:7625) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987) 
原因:java.lang.IllegalStateException:无法访问主线程上的数据库,因为它可能会长时间锁定UI。
位于androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:209)
位于androidx.room.RoomDatabase.query(RoomDatabase.java:237)
位于com.example.mykolproject.persistence.dao.NoteDao_Impl.getnAll(NoteDao_Impl.java:121)
在com.example.mykolproject.NoteRepository上(NoteRepository.java:23)
位于com.example.mykolproject.NoteViewModel。(NoteViewModel.java:20)
位于java.lang.reflect.Constructor.newInstance0(本机方法)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:343)
在androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200)
位于androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135)
位于androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103)
位于com.example.mykolproject.NotenActivity.onCreate(NotenActivity.java:130)
位于android.app.Activity.performCreate(Activity.java:7458)
位于android.app.Activity.performCreate(Activity.java:7448)
位于android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409)上
位于android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614)
在android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
在android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)中
在android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)中
在android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)上
位于android.os.Handler.dispatchMessage(Handler.java:112)
位于android.os.Looper.loop(Looper.java:216)
位于android.app.ActivityThread.main(ActivityThread.java:7625)
位于java.lang.reflect.Method.invoke(本机方法)
位于com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
以下是我受影响的活动:

package com.example.mykolproject.persistance.dao;

import android.database.Cursor;
import androidx.room.EntityDeletionOrUpdateAdapter;
import androidx.room.EntityInsertionAdapter;
import androidx.room.RoomDatabase;
import androidx.room.RoomSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteStatement;
import com.example.mykolproject.persistance.entities.Note;
import java.lang.Override;
import java.lang.String;
import java.lang.SuppressWarnings;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("unchecked")
public final class NoteDao_Impl implements NoteDao {
  private final RoomDatabase __db;

  private final EntityInsertionAdapter __insertionAdapterOfNote;

  private final EntityDeletionOrUpdateAdapter __deletionAdapterOfNote;

  private final EntityDeletionOrUpdateAdapter __updateAdapterOfNote;

  public NoteDao_Impl(RoomDatabase __db) {
    this.__db = __db;
    this.__insertionAdapterOfNote = new EntityInsertionAdapter<Note>(__db) {
      @Override
      public String createQuery() {
        return "INSERT OR ABORT INTO `note_table`(`id`,`titlefach`,`noten`) VALUES (nullif(?, 0),?,?)";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, Note value) {
        stmt.bindLong(1, value.getId());
        if (value.titlefach == null) {
          stmt.bindNull(2);
        } else {
          stmt.bindString(2, value.titlefach);
        }
        if (value.getNoten() == null) {
          stmt.bindNull(3);
        } else {
          stmt.bindString(3, value.getNoten());
        }
      }
    };
    this.__deletionAdapterOfNote = new EntityDeletionOrUpdateAdapter<Note>(__db) {
      @Override
      public String createQuery() {
        return "DELETE FROM `note_table` WHERE `id` = ?";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, Note value) {
        stmt.bindLong(1, value.getId());
      }
    };
    this.__updateAdapterOfNote = new EntityDeletionOrUpdateAdapter<Note>(__db) {
      @Override
      public String createQuery() {
        return "UPDATE OR ABORT `note_table` SET `id` = ?,`titlefach` = ?,`noten` = ? WHERE `id` = ?";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, Note value) {
        stmt.bindLong(1, value.getId());
        if (value.titlefach == null) {
          stmt.bindNull(2);
        } else {
          stmt.bindString(2, value.titlefach);
        }
        if (value.getNoten() == null) {
          stmt.bindNull(3);
        } else {
          stmt.bindString(3, value.getNoten());
        }
        stmt.bindLong(4, value.getId());
      }
    };
  }

  @Override
  public void insert(Note note) {
    __db.beginTransaction();
    try {
      __insertionAdapterOfNote.insert(note);
      __db.setTransactionSuccessful();
    } finally {
      __db.endTransaction();
    }
  }

  @Override
  public void delete(Note note) {
    __db.beginTransaction();
    try {
      __deletionAdapterOfNote.handle(note);
      __db.setTransactionSuccessful();
    } finally {
      __db.endTransaction();
    }
  }

  @Override
  public void update(Note note) {
    __db.beginTransaction();
    try {
      __updateAdapterOfNote.handle(note);
      __db.setTransactionSuccessful();
    } finally {
      __db.endTransaction();
    }
  }

  @Override
  public List<Note> getnAll() {
    final String _sql = "SELECT * FROM note_table";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    final Cursor _cursor = __db.query(_statement);
    try {
      final int _cursorIndexOfId = _cursor.getColumnIndexOrThrow("id");
      final int _cursorIndexOfTitlefach = _cursor.getColumnIndexOrThrow("titlefach");
      final int _cursorIndexOfNoten = _cursor.getColumnIndexOrThrow("noten");
      final List<Note> _result = new ArrayList<Note>(_cursor.getCount());
      while(_cursor.moveToNext()) {
        final Note _item;
        final String _tmpTitlefach;
        _tmpTitlefach = _cursor.getString(_cursorIndexOfTitlefach);
        final String _tmpNoten;
        _tmpNoten = _cursor.getString(_cursorIndexOfNoten);
        _item = new Note(_tmpTitlefach,_tmpNoten);
        final int _tmpId;
        _tmpId = _cursor.getInt(_cursorIndexOfId);
        _item.setId(_tmpId);
        _result.add(_item);
      }
      return _result;
    } finally {
      _cursor.close();
      _statement.release();
    }
  }
}
package com.example.mykolproject.persistence.dao;
导入android.database.Cursor;
导入androidx.room.EntityDeletion或UpdateDapter;
导入androidx.room.EntityInsertionAdapter;
导入androidx.room.RoomDatabase;
导入androidx.room.RoomSQLiteQuery;
导入androidx.sqlite.db.SupportSQLiteStatement;
导入com.example.mykolproject.persistence.entities.Note;
导入java.lang.Override;
导入java.lang.String;
导入java.lang.SuppressWarnings;
导入java.util.ArrayList;
导入java.util.List;
@抑制警告(“未选中”)
公共最终类NoteDao\u Impl实现NoteDao{
私人最终房间数据库uuu db;
专用最终实体InsertionAdapter\uu InsertionAdapter注释;
专用最终实体删除或更新适配器_删除适配器注释;
私有最终实体删除或UpdateDapter\uuu UpdateDapterOfNote;
公共NoteDao_Impl(房间数据库){
这是.uudb=uuudb;
此.\uuuu insertionadapter注释=新实体insertionadapter(\uuuu db){
@凌驾
公共字符串createQuery(){
返回“插入或中止到`note_table`(`id`、`titlefach`、`noten`)值(nullif(?,0),?,?)”;
}
@凌驾
公共void绑定(SupportSQLiteStatement stmt,注释值){
stmt.bindLong(1,value.getId());
if(value.titlefach==null){
stmt.bindNull(2);
}否则{
stmt.bindString(2,value.titlefach);
}
if(value.getNoten()==null){
stmt.bindNull(3);
}否则{
bindString(3,value.getNoten());
}
}
};
此{
@凌驾
公共字符串createQuery(){
返回“从`note_table`删除,其中`id`=?”;
}
@凌驾
公共void绑定(SupportSQLiteStatement stmt,注释值){
stmt.bindLong(1,value.getId());
}
};
此.\uuuuUpdateDapterOfNote=new EntityDeletion或UpdateDapter(\uuuuDB){
@凌驾
公共字符串createQuery(){
返回“UPDATE或ABORT`note\u table`SET`id`=?,`titlefach`=?,`noten`=?其中`id`=?”;
}
@凌驾
公共void绑定(SupportSQLiteStatement stmt,注释值){
stmt.bindLong(1,value.getId());
if(value.titlefach==null){
stmt.bindNull(2);
}否则{
stmt.bindString(2,value.titlefach);
}
if(value.getNoten()==null){
stmt.bindNull(3);
}否则{
bindString(3,value.getNoten());
}
stmt.bindLong(4,value.getId());
}
};
}
@凌驾
公共作废插入(注){
__db.beginTransaction();
试一试{
__插入适配器注释。插入(注释);
__db.setTransactionSuccessful();
}最后{
__db.endTransaction();
}
}
@凌驾
公共作废删除(注){
__db.beginTransaction();
试一试{
__删除适配器注释句柄(注释);
__db.setTransactionSuccessful();
}最后{
__db.endTransaction();
}
}
@凌驾
公共作废更新(注){
__db.beginTransaction();
试一试{
__updateAdapterOfNote.handle(注意);
__db.setTransactionSuccessful();
}最后{
__db.endTransaction();
}
}
@凌驾
公共列表getnAll(){
最后一个字符串_sql=“从注释表中选择*”;
final-RoomSQLiteQuery _语句=RoomSQLiteQuery.acquire(_-sql,0);
final Cursor\u Cursor=\uu db.query(\u语句);
试一试{
最终整数
package com.example.mykolproject;


import android.app.Application;
import android.os.AsyncTask;

import androidx.lifecycle.LiveData;

import com.example.mykolproject.persistance.dao.NoteDao;
import com.example.mykolproject.persistance.entities.AppDatabase;
import com.example.mykolproject.persistance.entities.Note;

import java.util.List;


public class NoteRepository {
    private NoteDao notenDao;
    private LiveData<List<Note>> allNoten;

    public NoteRepository(Application application) {
        AppDatabase database = AppDatabase.getInstance(application);
        notenDao = database.NoteDao();
        allNoten = (LiveData<List<Note>>) notenDao.getnAll();
    }

    public void insert(LiveData<List<Note>> note) {
        new InsertNoteAsyncTask(notenDao).execute((Runnable) note);
    }

    public void update(LiveData<List<Note>> note) {
        new UpdateNoteAsyncTask(notenDao).execute((Runnable) note);
    }

    public void delete(LiveData<List<Note>> note) {
        new DeleteNoteAsyncTask(notenDao).execute((Runnable) note);
    }


    public LiveData<List<Note>> getAllNoten() {
        return getAllNoten();
    }

    private static class InsertNoteAsyncTask extends AsyncTask<Note, Void, Void> {
        private NoteDao noteDao;

        private InsertNoteAsyncTask(NoteDao noteDao) {
            this.noteDao = noteDao;
        }

        @Override
        protected Void doInBackground(Note... noten) {
            noteDao.insert(noten[0]);
            return null;
        }
    }

    private static class UpdateNoteAsyncTask extends AsyncTask<Note, Void, Void> {
        private NoteDao noteDao;

        private UpdateNoteAsyncTask(NoteDao noteDao) {
            this.noteDao = noteDao;
        }

        @Override
        protected Void doInBackground(Note... noten) {
            noteDao.update(noten[0]);
            return null;
        }
    }

    private static class DeleteNoteAsyncTask extends AsyncTask<Note, Void, Void> {
        private NoteDao noteDao;

        private DeleteNoteAsyncTask(NoteDao noteDao) {
            this.noteDao = noteDao;
        }

        @Override
        protected Void doInBackground(Note... noten) {
            noteDao.delete(noten[0]);
            return null;
        }
    }


}
package com.example.mykolproject;

import android.app.Application;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;

import com.example.mykolproject.persistance.entities.Note;

import java.util.List;


public class NoteViewModel extends AndroidViewModel {
    private NoteRepository repository;
    private LiveData<List<Note>> allNoten;

    public NoteViewModel(@NonNull Application application) {
        super(application);
        repository = new NoteRepository(application);
        allNoten = repository.getAllNoten();
    }

    public void insert(Note note) {
        repository.insert(allNoten);
    }

    public void update(Note note) {
        repository.update(allNoten);
    }

    public void delete(Note note) {
        repository.delete(allNoten);
    }

    public LiveData<List<Note>> getAllNotes() {
        return allNoten;
    }
}
package com.example.mykolproject;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;


import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.mykolproject.persistance.entities.Note;

import java.util.List;


public class NotenActivity extends AppCompatActivity  {
    public String TAG = "NotenActivity";

    public static final String NOTEN_MESSAGE = "com.example.MyOLProject.NOTEN";

    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;

    public static final int ADD_NOTE_REQUEST = 1;
    public static final int EDIT_NOTE_REQUEST = 2;

    private NoteViewModel noteViewModel;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_noten);

        //  final EditText editFach = findViewById(R.id.edit_fach);


        recyclerView = (RecyclerView) findViewById(R.id.notenList);

        recyclerView.setHasFixedSize(true);

        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        Button btnAddNoten = findViewById(R.id.btn_addNote);

        btnAddNoten.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "onClick: AddNoten");
                startAddNoten();
            }
        });



        ImageButton btnFach = findViewById(R.id.ibFach);
        btnFach.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Log.i(TAG,"onClick: Fach");
                startFach();

            }

        });

        ImageButton btnHome = findViewById(R.id.ibHome);
        btnHome.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Log.i(TAG,"onClick: Home");
                startHome();

            }

        });

        ImageButton btnHausaufgaben = findViewById(R.id.ibHausaufgaben);
        btnHausaufgaben.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Log.i(TAG,"onClick: Hausaufgaben");
                startHausaufgaben();

            }

        });

        ImageButton btnKalender = findViewById(R.id.ibInfo);
        btnKalender.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Log.i(TAG,"onClick: Kalender");
                startKalender();

            }

        });

        Button buttonAddNote = findViewById(R.id.btn_addNote);
        buttonAddNote.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(NotenActivity.this, AddEditNoteActivity.class);
                startActivityForResult(intent, ADD_NOTE_REQUEST);
            }
        });

        RecyclerView recyclerView = findViewById(R.id.notenList);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);

        final NotenListAdapter adapter = new NotenListAdapter();
        recyclerView.setAdapter(adapter);

        noteViewModel = ViewModelProviders.of(this).get(NoteViewModel.class);
        noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>() {
            @Override
            public void onChanged(@Nullable List<Note> noten) {
                adapter.setNotes(noten);
            }
        });

        new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
                ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                noteViewModel.delete(adapter.getNoteAt(viewHolder.getAdapterPosition()));
                Toast.makeText(NotenActivity.this, "Note deleted", Toast.LENGTH_SHORT).show();
            }
        }).attachToRecyclerView(recyclerView);

        adapter.setOnItemClickListener(new NotenListAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(Note note) {
                Intent intent = new Intent(NotenActivity.this, AddEditNoteActivity.class);
                intent.putExtra(AddEditNoteActivity.EXTRA_ID, note.getId());
                intent.putExtra(AddEditNoteActivity.EXTRA_TITLE, note.getTitleFach());
                intent.putExtra(AddEditNoteActivity.EXTRA_DESCRIPTION, note.getNoten());
                startActivityForResult(intent, EDIT_NOTE_REQUEST);
            }
        });



    }


    private void startAddNoten(){
        Intent addNotenIntent = new Intent(this,AddNotenActivity.class);
        startActivity(addNotenIntent);
    }

    private void startFach(){
        Intent fachIntent = new Intent(this,FachActivity.class);
        startActivity(fachIntent);
    }
    private void startHome(){
        Intent homeIntent = new Intent(this,MainActivity.class);
        startActivity(homeIntent);
    }
    private void startHausaufgaben(){
        Intent hausaufgabenIntent = new Intent(this,HausaufgabenActivity.class);
        startActivity(hausaufgabenIntent);
    }
    private void startKalender(){
        Intent kalenderIntent = new Intent(this,InfoActivity.class);
        startActivity(kalenderIntent);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == ADD_NOTE_REQUEST && resultCode == RESULT_OK) {
            String title = data.getStringExtra(AddEditNoteActivity.EXTRA_TITLE);
            String description = data.getStringExtra(AddEditNoteActivity.EXTRA_DESCRIPTION);

            Note note = new Note(title, description);
            noteViewModel.insert(note);

            Toast.makeText(this, "Note saved", Toast.LENGTH_SHORT).show();
        } else if (requestCode == EDIT_NOTE_REQUEST && resultCode == RESULT_OK) {
            int id = data.getIntExtra(AddEditNoteActivity.EXTRA_ID, -1);

            if (id == -1) {
                Toast.makeText(this, "Note can't be updated", Toast.LENGTH_SHORT).show();
                return;
            }

            String title = data.getStringExtra(AddEditNoteActivity.EXTRA_TITLE);
            String description = data.getStringExtra(AddEditNoteActivity.EXTRA_DESCRIPTION);

            Note note = new Note(title, description);
            note.setId(id);
            noteViewModel.update(note);

            Toast.makeText(this, "Note updated", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "Note not saved", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.main_menu, menu);
        return true;
    }

   /* @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.delete_all_notes:
                noteViewModel.deleteAllNotes();
                Toast.makeText(this, "All notes deleted", Toast.LENGTH_SHORT).show();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}*/


}
import android.os.Looper;
import android.support.annotation.NonNull;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class AppExecutors {
    private static final Object LOCK = new Object();
    private static AppExecutors sInstance;
    private final Executor diskIO;
    private final Executor mainThread;
    private final Executor networkIO;

    private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
        this.diskIO = diskIO;
        this.networkIO = networkIO;
        this.mainThread = mainThread;
    }

    public static AppExecutors getInstance() {
        if (sInstance == null) {
            synchronized (LOCK) {
                sInstance = new AppExecutors(Executors.newSingleThreadExecutor(),
                        Executors.newFixedThreadPool(3),
                        new MainThreadExecutor());
            }
        }
        return sInstance;
    }

    public Executor diskIO() {
        return diskIO;
    }

    public Executor mainThread() {
        return mainThread;
    }

    public Executor networkIO() {
        return networkIO;
    }

    private static class MainThreadExecutor implements Executor {
        private Handler mainThreadHandler = new Handler(Looper.getMainLooper());

        @Override
        public void execute(@NonNull Runnable command) {
            mainThreadHandler.post(command);
        }
    }
}

//Then you can do something like this. 
```AppExecutors.getInstance().getDiskIO.execute(()->database.NoteDao().getnAll());```