Java 无法访问主线程上的数据库,因为它可能会长时间锁定UI错误
每当我想启动“NotenActivity”时,它都会显示以下错误: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
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());```