Как получить простой список <T>из Android LiveData? - PullRequest
0 голосов
/ 09 февраля 2019

Я новичок в 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 клиента -

@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
}

Класс репозитория Customer (показан частично)

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"

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

Используя getValue() на 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.

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

0 голосов
/ 09 февраля 2019

Вы должны вызывать метод

@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 где-нибудь в вашей Деятельности / Фрагменте (они реализуют LifecycleOwner).После того, как AsyncTask отправит значение, MainThread получит уведомление со значением.

Если вы не хотите соблюдать это LiveData, вы можете просто removeObservers, когда получите значение.

Для получения дополнительной информации, я предлагаю прочитать Документацию по LivaData.java

...