Ich habe eine Raumdatenbank nach dieser Anleitung aus Code-Labs erstellt. Sie verwendet ein Repository, um:
Ein Repository verwaltet Abfrage-Threads und ermöglicht Ihnen die Verwendung mehrerer Back-Ends. Im gängigsten Beispiel implementiert das Repository die Logik für die Entscheidung, ob Daten aus einem Netzwerk abgerufen oder in einer lokalen Datenbank zwischengespeicherte Ergebnisse verwendet werden sollen.
Ich habe die Anleitung befolgt und bin jetzt in der Lage, die Entität zu erstellen und die Daten abzurufen. Ich bin sogar noch weiter gegangen und habe eine andere ganze Entität außerhalb des Rahmens des Leitfadens erstellt.
Ich kann jedoch nicht viele Ressourcen finden, die diesen MVVM(?)-Stil verwenden, also habe ich Mühe, das Repository wirklich zu verstehen. Im Moment möchte ich ein Feld aktualisieren. Nur eins, als ob ich es hinbekomme, dass der Rest ähnlich sein sollte.
Ich möchte ein Feld namens Dartshit aktualisieren und habe die dao-Methode dafür erstellt:
@Query("UPDATE AtcUserStats SET dartsHit = :amount WHERE userName = :userName") void UpdateHitAmount(int Betrag, String userName);
Ich habe ein Repository, von dem ich annahm, dass ich es für alle Entitäten verwende:
public class UsersRepository {
private UsersDao mUsersDao;
private AtcDao mAtcDao;
private LiveData<List<Users>> mAllUsers;
private LiveData<List<AtcUserStats>> mAllAtc;
private AtcUserStats mAtcUser;
UsersRepository(Application application) {
AppDatabase db = AppDatabase.getDatabase(application);
mUsersDao = db.usersDao();
mAtcDao = db.atcDao();
mAllUsers = mUsersDao.fetchAllUsers();
mAllAtc = mAtcDao.getAllAtcStats();
}
LiveData<List<Users>> getAllUsers() {
return mAllUsers;
}
LiveData<List<AtcUserStats>> getAllAtcStats() {
return mAllAtc;
}
LiveData<AtcUserStats> getAtcUser(String username) {
return mAtcDao.findByName(username);
}
public void insert (Users user) {
new insertAsyncTask(mUsersDao).execute(user);
}
public void insertAtc (AtcUserStats atc) {
new insertAsyncAtcTask(mAtcDao).execute(atc);
}
private static class insertAsyncTask extends AsyncTask<Users, Void, Void> {
private UsersDao mAsyncTaskDao;
insertAsyncTask(UsersDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Users... params) {
mAsyncTaskDao.insertNewUser(params[0]);
return null;
}
}
private static class insertAsyncAtcTask extends AsyncTask<AtcUserStats, Void, Void> {
private AtcDao mAsyncTaskDao;
insertAsyncAtcTask(AtcDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final AtcUserStats... params) {
mAsyncTaskDao.insertNewAtcUser(params[0]);
return null;
}
}
}
Meine Frage ist, wie erstelle ich eine AsyncTask für die Update-Abfrage, die ich in diesem Repository ausführen möchte?
Folgendes habe ich bisher durch das weitgehende Kopieren der Insert-Repository-Methoden:
private class updateHitAsyncTask {
private AtcDao mAsyncTaskDao;
public updateHitAsyncTask(AtcDao mAtcDao) {
mAsyncTaskDao = mAtcDao;
}
protected Void doInBackground(int amount, String name) {
mAsyncTaskDao.UpdateHitAmount(amount, name);
return null;
}
}
Was falsch ist, ist, dass ich eine llegalStateException erhalte: Kann nicht auf die Datenbank im Hauptthread zugreifen, da die Benutzeroberfläche möglicherweise für längere Zeit gesperrt wird. Error. Aber ich dachte, diese AsyncTask soll sich darum kümmern?
Hier ist meine Update-Methode in meinem Ansichtsmodell, die 0 Fehler meldet:
void updateHitAmount (int amount, String name) {
mRepository.updateAtcHits(amount, name);
}
und hier ist der UI-Code, in dem ich tatsächlich versuche, all dies miteinander zu verknüpfen. Ich vermute, es muss einen besseren Weg geben als die Verwendung von onChanged zum einfachen Aktualisieren eines Felds, aber auch hier habe ich Schwierigkeiten, bei Google mit dem Repository-Ansatz auf Ratschläge zu stoßen:
private void callOnChanged() {
mAtcViewModel = ViewModelProviders.of(this).get(AtcViewModel.class);
mAtcViewModel.getAllUsers().observe(this, new Observer<List<AtcUserStats>>() {
@Override
public void onChanged(@Nullable final List<AtcUserStats> atc) {
// Update the cached copy of the users in the adapter.
for (int i = 0; i < atc.size(); i++) {
if (atc.get(i).getUserName().equals(mUser)) {
mAtcViewModel.updateHitAmount(55, mUser);
//atc.get(i).setDartsHit(55);
Log.d("id", String.valueOf(userSelected.getId()));
}
}
}
});
Wie kann ich Felder mit diesem Ansatz im Hintergrundthread aktualisieren?
Habe es aufgrund dieser Antwort hier herausgefunden . Es lag hauptsächlich an meinem mangelnden Verständnis von AsyncTask. Im Wesentlichen musste ich ein Objekt erstellen und die Daten auf diese Weise übergeben und dann im Hintergrund ausführen:
private static class MyTaskParams {
int amount;
String name;
MyTaskParams(int amount, String name) {
this.amount = amount;
this.name = name;
}
}
public void updateAtcHits (int amount, String name) {
MyTaskParams params = new MyTaskParams(amount,name);
new updateHitAsyncTask(mAtcDao).execute(params);
}
private class updateHitAsyncTask extends AsyncTask<MyTaskParams,Void,Void>{
private AtcDao mAsyncTaskDao;
public updateHitAsyncTask(AtcDao mAtcDao) {
mAsyncTaskDao = mAtcDao;
}
@Override
protected Void doInBackground(MyTaskParams... myTaskParams) {
int amount =myTaskParams[0].amount;
String name = myTaskParams[0].name;
mAsyncTaskDao.UpdateHitAmount(amount, name);
return null;
}
}
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen