Я пытаюсь загрузить loggedInUser из базы данных локальной комнаты, когда приложение запускается.Я хотел бы пропустить запрос пользователя на вход в систему, если сохраненный токен аутентификации ранее сохраненного пользователя все еще действителен!
Итак, из DAO , яхотите вернуть LiveData объект, содержащий ранее вошедшего в систему пользователя , затем наблюдать за последующими изменениями.Проблема, с которой я столкнулся, заключается в том, что метод получения текущего зарегистрированного пользователя всегда возвращает ноль , если я обертываю результат внутри LiveData , но он возвращает ожидаемого пользователя, если он возвращается как POJO .
Как заставить LiveData работать синхронно только для инициализации значения а затем слушать последующие изменения ?Я действительно хочу объединить эти два поведения, поскольку аутентификация может быть аннулирована с помощью фоновой задачи синхронизации или когда пользователь выходит из системы (эти действия либо заменят, либообновите сохраненный токен, и я хотел бы быть реактивным к таким обновлениям с помощью LiveData ).
Вот что у меня естьдо сих пор пробовал:
AuthorizationDAO.java
public interface AuthorizationDAO {
@Query("SELECT * FROM Authorization LIMIT 1") //Assume only one Authentication token will exist at any given time
LiveData<Authorization> getLoggedInUser(); //I want to keep this behaviour
@Insert(onConflict = REPLACE)
long insertAuth(Authorization authorization);
@Update
void logoutCurrentUser(Authorization authorization);
}
AuthorizationRepository.java
public class AuthorizationRepository {
private AuthorizationDAO mAuthorizationDAO;
private MutableLiveData<Authorization> mAuthorization = new MutableLiveData<>();
public AuthorizationRepository(Application application){
AppDatabase db = AppDatabase.getDatabase(application);
this.mAuthorizationDAO = db.mAuthorizationDAO();
}
public LiveData<Authorization> getLoggedInUser(){
mAuthorization.postValue(mAuthorizationDAO.getLoggedInUser().getValue()); //this is always null at startup
return this.mAuthorization;
}
AuthorizationViewModel.java
public class AuthorizationViewModel extends AndroidViewModel {
private AuthorizationRepository mAuthorizationRepository;
private LiveData<Resource<Authorization>> mAuthorization;
private LiveData<Authorization> loggedInUserAuth;
public AuthorizationViewModel(@NonNull Application application) {
super(application);
this.mAuthorizationRepository = new AuthorizationRepository(application);
}
public void init(){
this.loggedInUserAuth = this.mAuthorizationRepository.getLoggedInUser();
}
public LiveData<Authorization> getLoggedInUserAuth() {
return this.loggedInUserAuth;
}
}
AppActivity.java
public class AppActivity extends AppCompatActivity {
public AuthorizationViewModel mAuthorizationViewModel;
public @Nullable Authorization mAuthorization;
private NavController mNavController;
private NavHostFragment mNavHostFragment;
private BottomNavigationView mBottomNavigationView;
private boolean mIsLoggedIn;
private ActivityAppBinding mBinding;
private boolean mIsTokenExpired;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_app);
mNavHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.app_nav_host_fragment);
mNavController = mNavHostFragment.getNavController();
mBottomNavigationView = findViewById(R.id.nav_bottom_nav_view);
NavigationUI.setupWithNavController(mBottomNavigationView, mNavController);
if (Build.VERSION.SDK_INT>9){
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
mAuthorizationViewModel = ViewModelProviders.of(this).get(AuthorizationViewModel.class);
mAuthorizationViewModel.init(); //Here I want to load user synchronously before the rest happens and then on next line observe the same object
mAuthorizationViewModel.getLoggedInUserAuth().observe(this, new Observer<Authorization>() {
@Override
public void onChanged(@Nullable Authorization authorization) {
mBinding.setViewModel(authorization);
mIsLoggedIn = authorization == null? false: authorization.isLoggedIn();
mIsTokenExpired = authorization == null ? true : authorization.isTokenExpired();
if(!mIsLoggedIn || mIsTokenExpired){
if (authorization != null){
Log.i("CurrentAuth", "mIsLoggedIn?: "+authorization.isLoggedIn());
Log.i("CurrentAuth", "isTokenExpired?: "+authorization.isTokenExpired());
Log.i("CurrentAuth", "tokenCurrentTime?: "+ Calendar.getInstance().getTime());
Log.i("CurrentAuth", "tokenIssuedAt?: "+ authorization.getIat());
Log.i("CurrentAuth", "tokenExpiresAt?: "+ authorization.getExp());
}
mNavController.navigate(R.id.start_login);
}
}
});
Как видите, я звоню mAuthorizationViewModel.init () чтобы я мог загрузить или инициализировать loggedInUserAuth из локальной базы данных , а затем наблюдать то же самое LiveData экземпляр с mAuthorizationViewModel.getLoggedInUserAuth (). наблюдаем () на следующей строке!Но значение, возвращаемое для loggedInUserAuth , равно всегда null !
Пожалуйста, помогите, спасибо!