如何从Android LiveData <list <t >>获取简单的List <t>?

时间:2019-02-09 08:38:16

标签: android list android-room android-livedata getvalue

我是Android的新手,并通过开发一个简单的应用程序(该应用程序由我使用android Room数据库访问的单个Customer表)组成来学习该应用程序。

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

Customer 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 Repository类为(部分显示)

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:无法访问主线程上的数据库,因为它可能会长时间锁定UI。”

另一方面,如果我尝试通过执行另一个异步过程来获取客户列表,该过程成功返回LiveData列表,但是当我在LiveData上使用getValue()时返回null。

在我正在执行此任务的应用程序部分中,我既不希望检索到的列表会更改,也不需要将其呈现给用户。因此,我不需要观察此列表。我需要一个简单的列表,可以从中访问列表项并对其进行进一步处理。

我正在使用Android Studio 3.4 Canary 9,androidx room_version =“ 2.1.0-alpha03”,androix lifecycle_version =“ 2.0.0”

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中的

方法(它们实现LifecycleOwner)。在您的AsyncTask发布该值之后,MainThread将收到该值的通知。

如果您不希望看到此LiveData,则可以在获得值时只使用removeObservers

有关更多信息,我建议阅读LivaData.java上的文档

答案 1 :(得分:0)

通过在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都会触发,因此您可以自动处理更改。

有关更多信息,请参阅documentation,以了解如何使用LiveData

希望有帮助!