Я новичок в Android и изучаю то же самое, разрабатывая простое приложение, которое состоит из одной таблицы Customer, к которой я обращаюсь, используя базу данных Android Room.
Класс сущности Customer
@Entity(tableName = "Customers")
public class CustomerEntity {
@PrimaryKey(autoGenerate = true)
private int customerId;
private String customerName;
private String customerAddress;
private String customerZipCode;
private String customerEMailId;
}
Интерфейс клиента Дао
@Dao
public interface CustomerDao {
@Insert
public void insertCustomer( CustomerEntity customerEntity );
@Update
public void updateCustomer( CustomerEntity customerEntity );
@Delete
public void deleteCustomer( CustomerEntity customerEntity) ;
@Query("SELECT * FROM Customers")
LiveData<List<CustomerEntity>> getAllCustomers();
@Query("SELECT * FROM Customers WHERE customerZipCode == :givenZipCode ")
LiveData<List<CustomerEntity>> getGivenZipCodeCustomer( String givenZipCode);
@Query("SELECT * FROM Customers WHERE customerZipCode == :givenZipCode ")
List<CustomerEntity> getGivenZipCodeCustomerList( String givenZipCode);
@Query("SELECT * FROM Customers WHERE customerZipCode == :givenZipCode ")
Cursor getGivenZipCodeCustomerCursor(String givenZipCode
}
Класс репозитория клиентов (частично показан)
public List<CustomerEntity> getGivenZipCodeCustomersList(CustomerEntity customerEntity){
CustomerRepository.CustomerZipCodeAsyncTask customerZipCodeAsyncTask ;
customerZipCodeAsyncTask = new CustomerRepository.CustomerZipCodeAsyncTask( customerDao );
givenZipCodeCustomersList = customerZipCodeAsyncTask.doInBackground( customerEntity );
return givenZipCodeCustomersList ;
}
private static class CustomerZipCodeAsyncTask extends AsyncTask< CustomerEntity ,
Void , List < CustomerEntity > > {
private CustomerDao customerDao;
private CustomerZipCodeAsyncTask ( CustomerDao customerDao ){
this.customerDao = customerDao;
}
@Override
protected List < CustomerEntity > doInBackground(CustomerEntity... customerEntities) {
String zipCode = customerEntities[0].getCustomerZipCode();
return ( customerDao.getGivenZipCodeCustomerList( zipCode ) ) ;
}
}
Когда я пытаюсь получить список клиентов из другой части приложения, я получаю сообщение
"java.lang.IllegalStateException: Невозможно получить доступ к базе данных в главном потоке, так как это может потенциально заблокировать пользовательский интерфейс на длительный период времени."
С другой стороны, если я пытаюсь получить список клиентов, выполняя другой процесс Async, который успешно возвращает список LiveData, но возвращает null, когда я использую getValue() для LiveData.
В той части приложения, где я выполняю эту задачу, я не ожидаю, что извлеченный список изменится, и его не нужно представлять пользователю. Поэтому мне не нужно соблюдать этот список. Мне нужен простой список, из которого я могу получить доступ к элементам списка и обрабатывать их дальше.
Я использую Android Studio 3.4 Canary 9, androidx room_version = "2.1.0-alpha03", androix lifecycle_version = "2.0.0"
Вы должны призвать
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer)
@param owner The LifecycleOwner which controls the observer
@param observer The observer that will receive the events
метод для ваших LiveData где-нибудь в вашем Activity/Fragment (они реализуют LifecycleOwner
). После того, как AsyncTask отправит значение, MainThread получит уведомление со значением.
Если вы не хотите наблюдать эти LiveData
, вы можете просто removeObservers
когда получите значение.
Для получения дополнительной информации, я предлагаю прочитать Документацию на LivaData.java
Используя getValue()
для LiveData
, вы не используете всю мощь, на LiveData
способна LiveData
. В своем классе CustomerRepository
измените свой опубликованный метод на:
public LiveData<List<CustomerEntity>> getGivenZipCodeCustomersList(CustomerEntity customerEntity) {
String zipCode = customerEntity.getCustomerZipCode();
return customerDao.getGivenZipCodeCustomerList(zipCode);
}
Тогда ваша Activity
может выглядеть примерно так
public class MainActivity extends AppCompatActivity {
private CustomerRepository customerRepository;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
customerRepository = ... //init your repo here
CustomerEntity customerEntity = ... //init your customer entity here
customerRepository.getGivenZipCodeCustomersList(customerEntity).observe(this, new Observer<List<CustomerEntity>> {
@Override
public void onChanged(@Nullable List<CustomerEntity> customerEntities) {
//do stuff with your customerEntities here
}
});
//.. more code
}
}
При этом каждый раз, когда ваши клиенты, соответствующие почтовому индексу в вашем CustomerEntity
изменяют вашу базу данных, onChanged
получает триггер, чтобы вы могли обрабатывать изменения автоматически.
Для получения дополнительной информации обратитесь к документации о том, как использовать LiveData
.
Надеюсь, это поможет!