Как получить простой список <T> из Android LiveData <List <T >>?

1

Я новичок в 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"

Теги:
list
android-room
android-livedata

2 ответа

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

0

Используя 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.

Надеюсь, это поможет!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню