gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 09:07:54 25 4
gpt4 key购买 nike

每当我想启动我的“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) 

以下是我受影响的 Activity :

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;


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);
}
}
}*/


}
<小时/>

如果您需要任何其他 Activity ,请告诉我。我的“NotenActivity”就像我的 MainActivity。非常感谢!

最佳答案

尝试使用一些 RxJava,这可能会对您有所帮助。但由于您正在使用 Room、LiveData 和 ViewModel,您可以尝试使用此 AppExecutor 类。当我进行数据库和网络操作时,这通常会帮助我。

在 UI/主线程上运行时还要小心,对于包含大量数据的数据库操作,最佳实践始终是在单独的线程上执行此操作。

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());```

关于java - 无法在主线程上访问数据库,因为它可能会长时间锁定 UI 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60006121/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com