Je suis en train de charger le loggedInUser de la base de données Chambre locale, lorsque l'application démarre. Je voudrais passer vous sera demandé de vous identifier si le sauvé jeton d' authentification de l'utilisateur préalablement enregistré est toujours valide!
Ainsi, à partir du DAO , je veux retourner un LiveData objet contenant l' utilisateur connecté précédemment , puis observer pour les modifications ultérieures. Le défi que j'ai est que la méthode pour obtenir l'utilisateur actuellement connecté retourne toujours null si je conclurai le résultat dans une LiveData , mais il retourne l'utilisateur prévu si elle était renvoyée en POJO .
Comment puis - je forcer LiveData à exécuter de manière synchrone juste pour initialiser la valeur et ensuite écouter les modifications ultérieures ? Je veux vraiment combiner les deux comportements que l'authentification peut être invalidée par une tâche de synchronisation d'arrière - plan ou lorsque l' utilisateur se déconnecte (ces actions soit remplacer ou mettre à jour le jeton et je sauvé voudrais être réactive à ces mises à jour à l'aide de LiveData ).
Voici ce que je l'ai essayé jusqu'à présent:
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);
}
}
});
Comme vous pouvez le voir, je fais appel mAuthorizationViewModel.init () donc je peux charger ou initialiser la loggedInUserAuth à partir de la base de données locale , puis observer la même LiveData instance avec mAuthorizationViewModel.getLoggedInUserAuth (). Observer () sur la ligne suivante! Mais la valeur renvoyée pour loggedInUserAuth est toujours nul !
Aide Veuillez, merci!
Créer un getter de mAuthorization
la classeAuthorizationRepository
public MutableLiveData<Authorization> getAuthorizationResult() {
return mAuthorization;
}
Ensuite , modifiez votre AuthorizationViewModel
classe comme ci - dessous
public void init() {
mAuthorizationRepository.getLoggedInUser();
}
public LiveData<Authorization> getLoggedInUserAuth() {
return mAuthorizationRepository.getAuthorizationResult();
}