【发布时间】:2020-04-15 08:09:44
【问题描述】:
我尝试使用以下代码从我的数据库中加载一些数据并在活动中显示它们:
PhoneNumberViewModel phoneNumberViewModel =
new ViewModelProvider(WorksideContactCard.this).get(PhoneNumberViewModel.class);
phoneNumberViewModel
.getPhoneNumbersById(contactID)
.observe(this,
numbers -> {
phoneNumberList = numbers;
});
确切地说,我不需要观察数据的变化,因为如果活动恢复,数据将被刷新。但是上面的代码冻结了我的应用程序,尽管我在其他类中使用AsyncTask 访问数据库。
为什么会这样?
编辑:
PhoneNumberViewModel.class:
public class PhoneNumberViewModel extends AndroidViewModel {
private PhoneNumberRepository phoneNumberRepository;
private LiveData<List<PhoneNumber>> allPhoneNumbers;
public PhoneNumberViewModel(@NonNull Application application) {
super(application);
phoneNumberRepository = new PhoneNumberRepository(application);
allPhoneNumbers = phoneNumberRepository.getAllPhoneNumbersLive();
}
public void insert(PhoneNumber phoneNumber) {
System.out.println("[PhoneNumberRepository] Adding new phoneNumber");
phoneNumberRepository.insert(phoneNumber);
}
public void update(PhoneNumber phoneNumber) {
phoneNumberRepository.update(phoneNumber);
}
public void delete(PhoneNumber phoneNumber) {
phoneNumberRepository.delete(phoneNumber);
}
public LiveData<List<PhoneNumber>> getAllPhoneNumbers() {
return allPhoneNumbers;
}
public LiveData<List<PhoneNumber>> getPhoneNumbersById(long contactId)
throws ExecutionException, InterruptedException {
return phoneNumberRepository.getPhoneNumbersByContactId(contactId);
}
PhoneNumberRepository.class
public class PhoneNumberRepository {
private PhoneNumberDao phoneNumberDao;
private LiveData<List<PhoneNumber>> allPhoneNumbers;
private LiveData<List<PhoneNumber>> phoneNumbersByIdList;
public PhoneNumberRepository(Application application) {
WorksideDatabase database = WorksideDatabase.getInstance(application);
phoneNumberDao = database.phoneNumberDao();
allPhoneNumbers = phoneNumberDao.getAllPhoneNumbers();
}
...
public LiveData<List<PhoneNumber>> getAllPhoneNumbersLive() {
return allPhoneNumbers;
}
public void deleteAllPhoneNumbers() {
new DeleteAllPhoneNumbersAsyncTask(phoneNumberDao).execute();
}
public LiveData<List<PhoneNumber>> getPhoneNumbersByContactId(long id)
throws ExecutionException, InterruptedException {
return new SelectPhoneNumberByIdAsyncTask(phoneNumberDao, id).get();
}
private static class SelectPhoneNumberByIdAsyncTask
extends AsyncTask<Long, Void, LiveData<List<PhoneNumber>>> {
private PhoneNumberDao phoneNumberDao;
private Long ID;
private SelectPhoneNumberByIdAsyncTask(PhoneNumberDao phoneNumberDao, Long contactId) {
this.phoneNumberDao = phoneNumberDao;
ID = contactId;
}
@Override
protected LiveData<List<PhoneNumber>> doInBackground(Long... contactId) {
ID = contactId[0];
return phoneNumberDao.getPhoneNumbersById(ID);
}
}
...
}
PhoneNumberDao.class:
@Dao
public interface PhoneNumberDao {
@Insert
void insert(PhoneNumber phoneNumber);
@Update
void update(PhoneNumber phoneNumber);
@Delete
void delete(PhoneNumber phoneNumber);
// Probably uneeded method
@Query("DELETE FROM phone_numbers_table")
void deleteAllPhoneNumbers();
// Delete entry/entries by ID
@Query("DELETE FROM phone_numbers_table WHERE id = :phoneNumberId")
void deleteByPhoneNumberId(long phoneNumberId);
// Retrieve entry/entries by contact ID
// @Query("SELECT * FROM phone_numbers_table WHERE contact_id = :contactId")
// List<PhoneNumber> getPhoneNumbersById(long contactId);
// Retrieve all saved phone numbers in LiveData format
@Query("SELECT * FROM phone_numbers_table")
LiveData<List<PhoneNumber>> getAllPhoneNumbers();
@Query("SELECT * FROM phone_numbers_table WHERE contact_id = :contactId")
LiveData<List<PhoneNumber>> getPhoneNumbersById(long contactId);
@Query("SELECT * FROM phone_numbers_table")
List<PhoneNumber> getAll();
}
【问题讨论】:
-
你能把数据库初始化和异步任务的代码也贴出来吗...
-
@FaizanMir 嗨,我刚刚注意到我没有在这个特定片段中初始化数据库,也没有从中初始化
PhoneNumberDao对象。也许这是我的错误的根源? -
如果您使用 MVVM 模型并初始化存储库中的数据库,这不应该是一个问题,无论如何,如果这是应用程序将因 NullPointerException 而崩溃的问题,您可以添加一个 lil 位更准确的代码
-
@FaizanMir 相关课程添加到编辑后的答案中,如果您有任何想法,请告诉我。
-
我建议切换到 Kotlin 并使用协程,或者在这里你可以使用回调而不是使用阻塞主线程的 AsyncTask.get() 来处理这个问题
标签: java android android-asynctask android-room