1

I'm new to Android and learning the same by developing simple app which consists of single Customer table which I'm accessing using android Room database.

The Customer entity class is

@Entity(tableName = "Customers")
public class CustomerEntity {
@PrimaryKey(autoGenerate = true)
private int customerId;
private String customerName;
private String customerAddress;
private String customerZipCode;
private String customerEMailId;
}

The Customer Dao interface is

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

The Customer Repository class is (partly shown)

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

When I try to obtain the Customer List from the other part of app, I get the message

"java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time."

On the other hand, if I try to get Customer List by executing another Async process which returns LiveData List successfully but returns null when I use getValue() on LiveData.

In the part of app where I am doing this task, neither I expect that retrieved list will change nor it is required to be presented to user. So I do not need to observe this list. I need simple list from which I can access list items and process them further.

I am using Android Studio 3.4 Canary 9, androidx room_version = "2.1.0-alpha03", androix lifecycle_version = "2.0.0"

Zoe
  • 27,060
  • 21
  • 118
  • 148

2 Answers2

0

You should invoke

@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

method on your LiveData somewhere in your Activity/Fragment (They implement LifecycleOwner). After your AsyncTask posts the value, MainThread will then get notified with the value.

If you do not wish to observe this LiveData, you can just removeObservers when you get the value.

For more information, I suggest to read Documentation on LivaData.java

Kuba Pawłowski
  • 365
  • 2
  • 10
0

By using getValue() on LiveData, you're not using the full power of what LiveData is capable of. In your CustomerRepository class, change your posted method to:

public LiveData<List<CustomerEntity>> getGivenZipCodeCustomersList(CustomerEntity customerEntity) {
  String zipCode = customerEntity.getCustomerZipCode();
  return customerDao.getGivenZipCodeCustomerList(zipCode);
}

Then your Activity could look something like

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

Doing this, every time your customers matching to the zipcode in your CustomerEntity change in your database, onChanged gets trigger so you can handle the changes automatically.

For more info, refer to the documentation of how to use LiveData.

Hope that helps!