获取 LiveData 的初始值总是返回 Null
Getting Initial Value for LiveData Always Returning Null
我正在尝试在应用程序启动时从本地房间数据库加载 loggedInUser。如果之前保存的用户的 Authentication Token 仍然有效,我想跳过提示用户登录!
所以,从 DAO,我想 return 一个 LiveData 对象包含 之前登录用户,然后观察它以进行后续更改。我面临的挑战是,如果我将结果包装在 LiveData[=68 中,则获取当前登录用户 的方法总是 returns null =],但如果 return 编辑为 POJO,则它 return 是预期的用户。
如何强制 LiveData 运行 同步 只是 initialize 值然后监听后续变化?我真的想结合这两种行为,因为身份验证可能 无效 由 后台同步任务 或当 用户注销时(这些操作将替换或更新已保存的令牌,我想在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 来自 本地数据库 ,然后 observe 相同的 LiveData 实例mAuthorizationViewModel.getLoggedInUserAuth().observe() 在下一行!但是 loggedInUserAuth 的值 returned 是 always null!
请帮忙,谢谢!
在classAuthorizationRepository
中创建mAuthorization
的getter方法
public MutableLiveData<Authorization> getAuthorizationResult() {
return mAuthorization;
}
然后像下面这样修改你的AuthorizationViewModel
class
public void init() {
mAuthorizationRepository.getLoggedInUser();
}
public LiveData<Authorization> getLoggedInUserAuth() {
return mAuthorizationRepository.getAuthorizationResult();
}
在@Krishna 的大力帮助下,我终于解决了这个问题,这里是要点:
- DAO 方法 应该return LiveData
- 在 Repository class 中,创建一个 LiveData 私有成员变量 而不是 MutableLiveData(这是因为我们将通过 updates/inserts 改变数据库记录)。成员变量将保存对 LiveData 对象的引用 return 由 DAO 方法
编辑
- 在Repository的构造函数中,初始化 LiveData对象到结果return由 DAO 方法编辑。这样每次activity启动时,都会加载当前保存的记录
- 在 存储库 class 中,创建一个 getter,它将公开 LiveData 对象到 ViewModel
- 在 ViewModel class 中,创建一个将 LiveData 对象公开给 的方法视图控制器(activity 或片段)
- 在 Activity 或 Fragment 中,只需收听或订阅 到 LiveData[ 上的变化=72=] 由 ViewModel
提供的 Accessor Method 公开
- DAO 也可以公开一个方法来更新 LiveData,允许 Repository通过 ViewModel 启用 Activity 或 Fragment 将更新发送到 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); //this will be used to toggle login status by Activity or Fragment
}
AuthorizationRepository.java
public class AuthorizationRepository {
private AuthorizationDAO mAuthorizationDAO;
private AuthorizationWebAPI mAuthorizationWebAPI;
private LiveData<Authorization> mAuthorization; //reference to returned LiveData
public AuthorizationRepository(Application application){
AppDatabase db = AppDatabase.getDatabase(application);
this.mAuthorizationDAO = db.mAuthorizationDAO();
this.mAuthorization = mAuthorizationDAO.getLoggedInUser(); //initialize LiveData
}
public LiveData<Authorization> getAuthorizationResult() { //getter exposing LiveData
return mAuthorization;
}
public void logoutCurrentUser(){ //toggle login status
if (this.mAuthorization != null){
AppExecutors.getInstance().getDiskIO().execute(()->{
Authorization mAuthorizationObj = this.mAuthorization.getValue();
mAuthorizationObj.setLoggedIn(false);
mAuthorizationDAO.logoutCurrentUser(mAuthorizationObj); //update LiveData and changes will be broadcast to all listeners
});
}
}
}
AuthorizationViewModel.java
public class AuthorizationViewModel extends AndroidViewModel {
private AuthorizationRepository mAuthorizationRepository;
public AuthorizationViewModel(@NonNull Application application) {
super(application);
this.mAuthorizationRepository = new AuthorizationRepository(application);
}
public LiveData<Authorization> getLoggedInUserAuth() { //exposes LiveData to the Activity or Fragment
return mAuthorizationRepository.getAuthorizationResult();
}
public void logoutCurrentUser(){ //allows activity or fragment to toggle login status
this.mAuthorizationRepository.logoutCurrentUser();
}
}
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);
mAuthorizationViewModel = ViewModelProviders.of(this).get(AuthorizationViewModel.class);
mAuthorizationViewModel.getLoggedInUserAuth().observe(this, new Observer<Authorization>() { //Observe changes to Authorization LiveData exposed by getLoggedInUserAuth()
@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", "tokenExpiresAt?: "+ authorization.getExp());
}
mNavController.navigate(R.id.start_login); //every time authorization is changed, we check if valid else we react by prompting user to login
}
}
});
}
}
LogoutFragment.java
public class LogoutFragment extends Fragment {
private AuthorizationViewModel mAuthorizationViewModel;
private Authorization mAuth;
private FragmentLogoutBinding mBinding;
public LogoutFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mAuthorizationViewModel = ViewModelProviders.of(getActivity()).get(AuthorizationViewModel.class);
mAuthorizationViewModel.getLoggedInUserAuth().observe(getActivity(), new Observer<Authorization>() {
@Override
public void onChanged(Authorization authorization) {
mAuth = authorization;
}
});
// Inflate the layout for this fragment
mBinding = DataBindingUtil.inflate(inflater,R.layout.fragment_logout,container,false);
View view = mBinding.getRoot();
mBinding.setViewModel(mAuth);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
new AlertDialog.Builder(getContext())
.setTitle(R.string.title_logout_fragment)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
mAuthorizationViewModel.logoutCurrentUser(); //toggle login status, this will mutate LiveData by updating the database record then UI will react and call login fragment
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
Navigation.findNavController(view).popBackStack();
}
})
.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
}
})
.show();
}
}
为时已晚,但可能会对某人有所帮助。
我在执行此操作时遇到了同样的问题
MyDao myDao;
private LiveData<List<T>> liveList;
//in constructor of repo after initializing myDao;
this.liveList = myDao.getAllData();
//somewhere in repo
for(T t : liveList.getValue()){/*computation*/}
我就是这样解决的
MyDao myDao;
//in constructor of repo don't do this because called on main thread
this.list = myDao.getAll();
//in constructor of repo initialize your Dao (in this case myDao)
//somewhere in repo (must not be on main thread)
for(T t : myDao.getAll()){/*computation*/} //do this on background thread
在 MyDao 中
@Query("SELECT * FROM myTable")
List<T> getAll();
@Query("SELECT * FROM myTable")
LiveData<List<T>> getAllData();
或者,如果您在其他地方(不是存储库)访问 liveList,那么您必须为相同的地方设置一个观察者
我正在尝试在应用程序启动时从本地房间数据库加载 loggedInUser。如果之前保存的用户的 Authentication Token 仍然有效,我想跳过提示用户登录!
所以,从 DAO,我想 return 一个 LiveData 对象包含 之前登录用户,然后观察它以进行后续更改。我面临的挑战是,如果我将结果包装在 LiveData[=68 中,则获取当前登录用户 的方法总是 returns null =],但如果 return 编辑为 POJO,则它 return 是预期的用户。
如何强制 LiveData 运行 同步 只是 initialize 值然后监听后续变化?我真的想结合这两种行为,因为身份验证可能 无效 由 后台同步任务 或当 用户注销时(这些操作将替换或更新已保存的令牌,我想在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 来自 本地数据库 ,然后 observe 相同的 LiveData 实例mAuthorizationViewModel.getLoggedInUserAuth().observe() 在下一行!但是 loggedInUserAuth 的值 returned 是 always null!
请帮忙,谢谢!
在classAuthorizationRepository
mAuthorization
的getter方法
public MutableLiveData<Authorization> getAuthorizationResult() {
return mAuthorization;
}
然后像下面这样修改你的AuthorizationViewModel
class
public void init() {
mAuthorizationRepository.getLoggedInUser();
}
public LiveData<Authorization> getLoggedInUserAuth() {
return mAuthorizationRepository.getAuthorizationResult();
}
在@Krishna 的大力帮助下,我终于解决了这个问题,这里是要点:
- DAO 方法 应该return LiveData
- 在 Repository class 中,创建一个 LiveData 私有成员变量 而不是 MutableLiveData(这是因为我们将通过 updates/inserts 改变数据库记录)。成员变量将保存对 LiveData 对象的引用 return 由 DAO 方法 编辑
- 在Repository的构造函数中,初始化 LiveData对象到结果return由 DAO 方法编辑。这样每次activity启动时,都会加载当前保存的记录
- 在 存储库 class 中,创建一个 getter,它将公开 LiveData 对象到 ViewModel
- 在 ViewModel class 中,创建一个将 LiveData 对象公开给 的方法视图控制器(activity 或片段)
- 在 Activity 或 Fragment 中,只需收听或订阅 到 LiveData[ 上的变化=72=] 由 ViewModel 提供的 Accessor Method 公开
- DAO 也可以公开一个方法来更新 LiveData,允许 Repository通过 ViewModel 启用 Activity 或 Fragment 将更新发送到 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); //this will be used to toggle login status by Activity or Fragment
}
AuthorizationRepository.java
public class AuthorizationRepository {
private AuthorizationDAO mAuthorizationDAO;
private AuthorizationWebAPI mAuthorizationWebAPI;
private LiveData<Authorization> mAuthorization; //reference to returned LiveData
public AuthorizationRepository(Application application){
AppDatabase db = AppDatabase.getDatabase(application);
this.mAuthorizationDAO = db.mAuthorizationDAO();
this.mAuthorization = mAuthorizationDAO.getLoggedInUser(); //initialize LiveData
}
public LiveData<Authorization> getAuthorizationResult() { //getter exposing LiveData
return mAuthorization;
}
public void logoutCurrentUser(){ //toggle login status
if (this.mAuthorization != null){
AppExecutors.getInstance().getDiskIO().execute(()->{
Authorization mAuthorizationObj = this.mAuthorization.getValue();
mAuthorizationObj.setLoggedIn(false);
mAuthorizationDAO.logoutCurrentUser(mAuthorizationObj); //update LiveData and changes will be broadcast to all listeners
});
}
}
}
AuthorizationViewModel.java
public class AuthorizationViewModel extends AndroidViewModel {
private AuthorizationRepository mAuthorizationRepository;
public AuthorizationViewModel(@NonNull Application application) {
super(application);
this.mAuthorizationRepository = new AuthorizationRepository(application);
}
public LiveData<Authorization> getLoggedInUserAuth() { //exposes LiveData to the Activity or Fragment
return mAuthorizationRepository.getAuthorizationResult();
}
public void logoutCurrentUser(){ //allows activity or fragment to toggle login status
this.mAuthorizationRepository.logoutCurrentUser();
}
}
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);
mAuthorizationViewModel = ViewModelProviders.of(this).get(AuthorizationViewModel.class);
mAuthorizationViewModel.getLoggedInUserAuth().observe(this, new Observer<Authorization>() { //Observe changes to Authorization LiveData exposed by getLoggedInUserAuth()
@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", "tokenExpiresAt?: "+ authorization.getExp());
}
mNavController.navigate(R.id.start_login); //every time authorization is changed, we check if valid else we react by prompting user to login
}
}
});
}
}
LogoutFragment.java
public class LogoutFragment extends Fragment {
private AuthorizationViewModel mAuthorizationViewModel;
private Authorization mAuth;
private FragmentLogoutBinding mBinding;
public LogoutFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mAuthorizationViewModel = ViewModelProviders.of(getActivity()).get(AuthorizationViewModel.class);
mAuthorizationViewModel.getLoggedInUserAuth().observe(getActivity(), new Observer<Authorization>() {
@Override
public void onChanged(Authorization authorization) {
mAuth = authorization;
}
});
// Inflate the layout for this fragment
mBinding = DataBindingUtil.inflate(inflater,R.layout.fragment_logout,container,false);
View view = mBinding.getRoot();
mBinding.setViewModel(mAuth);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
new AlertDialog.Builder(getContext())
.setTitle(R.string.title_logout_fragment)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
mAuthorizationViewModel.logoutCurrentUser(); //toggle login status, this will mutate LiveData by updating the database record then UI will react and call login fragment
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
Navigation.findNavController(view).popBackStack();
}
})
.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
}
})
.show();
}
}
为时已晚,但可能会对某人有所帮助。
我在执行此操作时遇到了同样的问题
MyDao myDao;
private LiveData<List<T>> liveList;
//in constructor of repo after initializing myDao;
this.liveList = myDao.getAllData();
//somewhere in repo
for(T t : liveList.getValue()){/*computation*/}
我就是这样解决的
MyDao myDao;
//in constructor of repo don't do this because called on main thread
this.list = myDao.getAll();
//in constructor of repo initialize your Dao (in this case myDao)
//somewhere in repo (must not be on main thread)
for(T t : myDao.getAll()){/*computation*/} //do this on background thread
在 MyDao 中
@Query("SELECT * FROM myTable")
List<T> getAll();
@Query("SELECT * FROM myTable")
LiveData<List<T>> getAllData();
或者,如果您在其他地方(不是存储库)访问 liveList,那么您必须为相同的地方设置一个观察者