ViewModel, данные которого основаны на асинхронной задаче - PullRequest
0 голосов
/ 01 октября 2018

Меня просто смущает идея ViewModel, когда у вас есть данные, загружаемые асинхронно.

Вот пример ViewModel

public class UsersViewModel extends ViewModel {

     private List<User> userList;

     public List<User> getUserList() {
        if (userList == null) {
             usersList = loadUsers();
         }
         return userList;
     }

     private List<User> loadUsers() {
         // This is async task
     }
 }

Activity:

public class UsersActivity extends AppCompatActivity {

     @Override
     protected void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);

         UsersViewModel usersViewModel =
             ViewModelProviders.of(this).get(UsersViewModel.class);

         showUsers(usersViewModel.getUserList());
     }
 }

Это покажет пустой список (или, возможно, сбой при нулевом), так как асинхронная задача не была выполнена.Все примеры, которые я видел в Интернете, были синхронно блокирующими вызовами.Но как насчет случаев, когда это асинхронный вызов, который получает данные с сервера и обновляет пользовательский интерфейс в результате.Как мы справимся с этим?

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Как Фелипе Р. предложил в своем ответе, вы можете достичь этого с помощью LiveData, но я скажу, что вам не стоит останавливаться на достигнутом.

Реальная сила компонентов архитектуры Android проявляется, когда вы используете все

  • ViewModel - значительно упростит вашу жизнь, когда вы захотите обновить пользовательский интерфейс из фоновых потоков или других длительных процессов, так как они связаны с жизненным циклом Activit / Fragment, нонезависимым образом, так что больше нет NPE для представлений, которые удаляются из окна, когда AsyncTask публикует результат задания.
  • LiveData - поможет вам передавать данные из ViewModel в пользовательский интерфейс, не беспокоясь окакая нить вернула ответ.LiveData можно заменить на RxJava или Rx для Kotlin, но я предпочитаю его для обновлений пользовательского интерфейса
  • Привязка данных - поможет вам «автоматически обновлять» пользовательский интерфейс при наличии информации, а также избавит вас от некоторых NPE извремя от времени.

Из этих трех компонентов, я думаю, ViewModel - единственный, который является своего рода бессмысленным для использования его собственным.Два других могут принести некоторые преимущества, но вся мощь приходит, когда вы используете их все.У вас также будет отличное время для написания тестов для вашей реализации.

0 голосов
/ 02 октября 2018

Вы можете достичь этого, используя живые данные.ViewModel вернет MutableLiveData и, по вашему мнению, вы подпишетесь на любые изменения значений.

Вы также можете использовать привязку данных, тогда ваши данные при просмотре автоматически изменятся.

public class NameViewModel extends ViewModel {

    // Create a LiveData with a String
    private MutableLiveData<String> mCurrentName;

    public MutableLiveData<String> getCurrentName() {
      if (mCurrentName == null) {
        mCurrentName = new MutableLiveData<String>();
      }
      return mCurrentName;
    }

 // Rest of the ViewModel...
}

Тогдав вашей деятельности:

public class NameActivity extends AppCompatActivity {

  private NameViewModel mModel;

   @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Other code to setup the activity...

    // Get the ViewModel.
    mModel = ViewModelProviders.of(this).get(NameViewModel.class);


    // Create the observer which updates the UI.
    final Observer<String> nameObserver = new Observer<String>() {
        @Override
        public void onChanged(@Nullable final String newName) {
            // Update the UI, in this case, a TextView.
            mNameTextView.setText(newName);
        }
    };

    // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
    mModel.getCurrentName().observe(this, nameObserver);
  }
}

https://developer.android.com/topic/libraries/architecture/livedata

...