ViewModel и LiveData не удаляются после закрытия приложения.Зачем? - PullRequest
0 голосов
/ 04 июля 2019

Я только начал изучать разработку Android и у меня возникла проблема, я рад любой помощи.

Когда я нажимаю «Пользователь существует?» Кнопка, запрос отправляется на сервер и сервер возвращает либо пользователя, либо значение NULL (в моем случае всегда NULL, поскольку на сервере не создано ни одного пользователя).

После нажатия на кнопку в обозревателе в журнале отображается следующее:

UserResult onChanged

UserResult NOT NULL

UserResult false null

То есть все работает отлично.

Когда я закрываю приложение нажатием кнопки «Назад», я вижу в журналах, что onDestroy вызывается для активности, а onCleared вызывается для ViewModel.

Но если я даже через час снова запускаю приложение, то сразу отображается журнал (без нажатия кнопки):

UserResult onChanged

UserResult NOT NULL

UserResult false null

Но если после закрытия приложения я выполняю очистку всех запущенных приложений через операционную систему, то в журнале ничего не отображается.

Почему ViewModel и LiveData не были удалены даже через час после закрытия приложения? Я думаю, что я делаю что-то не так, пожалуйста, помогите мне понять, в чем моя ошибка Спасибо.

ViewModel

class UserViewModel extends ViewModel {

    private MutableLiveData<UserResult> userResult;
    private UserRepository userRepository;

    LiveData<UserResult> getUserResult() {
        return userResult;
    }

    UserViewModel(UserRepository userRepository) {
        this.userRepository = userRepository;
        userResult = userRepository.getUser(null);
    }

    void getUser(String username) {
        userResult = userRepository.getUser(username);
    }

    @Override
    protected void onCleared() {
        Log.d(TAG, "onCleared");
        super.onCleared();
    }
}

Репозиторий

public class UserRepository {
    ...

    private WebServiceApi webServiceApi;

    private MutableLiveData<UserResult> data = new MutableLiveData<>();

    public MutableLiveData<UserResult> getUser(String username) {
        if (username != null) {
            webServiceApi.getUser(username).enqueue(new Callback<User>() {
                @Override
                public void onResponse(Call<User> call, Response<User> response) {
                    User user = response.body();
                    if (user == null) {
                        // first param = user, second param = userExistsFlag(true when user not null, false when user is null)
                        data.setValue(new UserResult(null, false));
                    } else {
                        data.setValue(new UserResult(user, true));
                    }
                }

                @Override
                public void onFailure(Call<User> call, Throwable t) {
                    Log.d("UserRepository", "onFailure " + t.getMessage());
                }
            });
        }

        return data;
    }
}

Активность

public class UserActivity extends AppCompatActivity {
    ...
    private UserViewModel userViewModel;


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user);

        ...

        userViewModel.getUserResult().observe(this, new Observer<UserResult>() {
            @Override
            public void onChanged(@Nullable UserResult userResult) {
                Log.d(TAG, "UserResult onChanged");

                if (userResult == null) {
                    return;
                } else {
                    Log.d(TAG, "UserResult NOT NULL");
                    Log.d(TAG, "UserResult " + userResult.getUserExistsFlag() + " " + userResult.getUser());
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG, "onDestroy");
        super.onDestroy();
    }

}

1 Ответ

0 голосов
/ 04 июля 2019

Там нет никакой ошибки. Это ожидаемое поведение. ОС Android обычно не завершает процессы приложения, когда пользователь закрывает приложение. Есть несколько обстоятельств, что ОС убивает процессы, но закрытие приложения пользователем не является одним из них.

Если приложение живое, это означает, что все одноэлементные классы не будут собираться мусором. Ваши ViewModels будут отброшены, но UserRepository и все его переменные-члены не будут, если UserRepository каким-то образом использует шаблон синглтона. Вероятно, поэтому ваш MutableLiveData<UserResult> data немедленно возвращает значение.

Если вам не нравится это поведение, вы, вероятно, не должны держать ниже строки в UserRepository.

    private MutableLiveData<UserResult> data = new MutableLiveData<>();
...