title: Observe LiveData in non-View or non-ViewModel class
body: <p>I have an application that allows a user to enter their credentials into a Fragment which then inserts or updates a record in a Room database.  The transaction is handled by a CredentialsRepository.</p>
  
  <p>On the networking side, I have a DataRepository that works with a NetworkServiceController to create calls to my remote API.  In order to access the remote API I have an interceptor that adds the user credentials to each call.</p>
  
  <p>What I need is to load those credentials when the application loads, and whenever the data in the Room database changes.  I can do this using LiveData in my login screen (a View), but how can I observe the user credential data in my DataRepository using LiveData?</p>
  
  <p>How do I register my DataRepository class as an Observer?  Right now my app crashes...I am pretty sure the way I am registering the observer is wrong.</p>
  
  <p>Here is my CredentialsRepository:</p>
  
  <pre><code>    import androidx.lifecycle.LiveData;
      import ca.thirdgear.homeautomation.HomeAutomationApp;
      import ca.thirdgear.homeautomation.dao.UserCredentialsDAO;
      import ca.thirdgear.homeautomation.entity.UserCredentials;
      import javax.inject.Inject;
      import javax.inject.Singleton;
  
      /**
       * Repository Class for data from the Room Database
       */
      @Singleton
      public class CredentialsRepository
      {
          @Inject
          UserCredentialsDAO credentialsDAO;
  
          @Inject
          public CredentialsRepository()
          {
              HomeAutomationApp.getAppComponent().inject(this);
          }
  
          public void setCredentials(String userEmail, String password)
          {
              //create UserCredentials object with the credentials provided from the UI.
              UserCredentials newOrUpdatedUserCredentials = new UserCredentials(userEmail, password);
  
              //insert user credentials into the database
              Runnable myRunnableObject = new SetUserCredentials(credentialsDAO, newOrUpdatedUserCredentials);
              new Thread(myRunnableObject).start();
          }
  
          public LiveData&lt;UserCredentials&gt; getCredentials()
          {
              return credentialsDAO.getUser();
          }
      }
  </code></pre>
  
  <p>Here is my DataRepositoryClass</p>
  
  <pre><code>    /**
       * Repository class for handling network calls to REST API
       */
      @Singleton
      public class DataRepository
      {
          //Network components
          @Inject
          NetworkServiceController networkServiceController;
  
          @Inject
          UserCredentialsDAO credentialsDAO;
  
          @Inject
          CredentialsRepository credRepo;
  
          private HomeAutomationAPI homeAutomationAPIService;
          private MutableLiveData&lt;String&gt; zoneOneState;
          private MutableLiveData&lt;String&gt; zoneTwoState;
          private MutableLiveData&lt;String&gt; garageDoorState;
          private MutableLiveData&lt;String&gt; adtSystemState;
          private MutableLiveData&lt;String&gt; panelTemperature;
          private String username;
          private String password;
  
  
          @Inject
          public DataRepository()
          {
              //Inject Network Backend Components &amp; Room DAO
              HomeAutomationApp.getAppComponent().inject(this);
  
              //create credentials observer
              final Observer&lt;UserCredentials&gt; credentialsObserver = new Observer&lt;UserCredentials&gt;() {
                  @Override
                  public void onChanged(UserCredentials userCredentials)
                  {
                      //update string values for credentials
                      username = userCredentials.getUsername();
                      password = userCredentials.getPassword();
  
                      //call createNetworkService() to create a new network service object
                      createNetworkService();
                  }
              };
  
              //register the observer
              //this does not work...app crashes
              credRepo.getCredentials().observeForever(credentialsObserver);
  
              zoneOneState = new MutableLiveData&lt;&gt;();
              zoneTwoState = new MutableLiveData&lt;&gt;();
              garageDoorState = new MutableLiveData&lt;&gt;();
              adtSystemState = new MutableLiveData&lt;&gt;();
              panelTemperature = new MutableLiveData&lt;&gt;();
  
              //Poll the server every 5 seconds on a separate thread for changes in the IO
              Thread thread = new Thread(new Runnable(){
                  public void run()
                  {
                      // Moves the current Thread into the background
                      android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
  
                      while(true)
                      {
                          try {
                              sleep(5000);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          getIoStatus();
                      }
                  }
              });
              thread.start();
          }
  
          /*
               Create the network service when there are changes in the user credentials data.
           */
            private void createNetworkService()
            {
                homeAutomationAPIService = networkServiceController.createService(HomeAutomationAPI.class, username, password);
            }
  
  
          ... deleted methods not relevant ...
  
      }
  </code></pre>
  
  <p><strong>EDIT:</strong>
  Observer registration can occur in DataRepository like this:</p>
  
  <pre><code>credRepo.getCredentials().observeForever(credentialsObserver);
  </code></pre>
  
  <p>or like this:</p>
  
  <pre><code>credentialsDAO.getUser().observeForever(credentialsObserver);
  </code></pre>
  
  <p>However, I need to create the network service in the constructor by calling:</p>
  
  <pre><code>createNetworkService();
  </code></pre>
  
  <p>Otherwise the application still crashes.</p>
  
  <p>My application now works with the addition of the line of code above, but a new problem has been created.  When the application is launched in a new process, it takes several seconds before any network data is available.  My guess is that DataRepository creation takes place faster than data can be retrieved from the database, and my network services is initially created with null or unknown user credentials.  Is this a correct assumption?</p>