我在探索谷歌的Android架构组件.在我的项目中,我依赖于Services和IntentServices.从IntentService或Service 与app的ViewModel通信的正确方法是什么?使用LiveData可以实现吗?
android mvvm android-viewmodel android-architecture-components
我的问题与ViewModel有关,第二次返回null,其中observe如果我重复调用服务器,我在函数中没有得到回调.以下是我使用的代码 -
@Singleton
public class NetworkInformationViewModel extends AndroidViewModel {
private LiveData<Resource<NetworkInformation>> networkInfoObservable;
private final APIClient apiClient;
@Inject
NetworkInformationViewModel(@NonNull APIClient apiClient, @NonNull Application application) {
super(application);
this.apiClient = apiClient;
getNetworkInformation();
}
public LiveData<Resource<NetworkInformation>> getNetworkInfoObservable() {
return networkInfoObservable;
}
// making API calls and adding it to Observable
public void getNetworkInformation() {
networkInfoObservable = apiClient.getNetworkInformation();
}
}
Run Code Online (Sandbox Code Playgroud)
在Activity中,ViewModel定义如下 -
final NetworkInformationViewModel networkInformationViewModel =
ViewModelProviders.of(this, viewModelFactory).get(NetworkInformationViewModel.class);
observeViewModel(networkInformationViewModel);
Run Code Online (Sandbox Code Playgroud)
该observeViewModel函数用于添加observable ViewModel.
public void observeViewModel(final NetworkInformationViewModel networkInformationViewModel) …Run Code Online (Sandbox Code Playgroud) android android-livedata android-architecture-lifecycle android-viewmodel android-architecture-components
我在app中关注MMVM架构,Everything工作正常,直到我使用以下代码从ViewModel启动活动时崩溃.使用数据绑定从XML调用方法并将其view作为参数传递,并且getApplication()是AndroidViewModel类中的方法.
getApplication().startActivity(new Intent(view.getContext(), MyActivity.class));
Run Code Online (Sandbox Code Playgroud)
我相信这是因为我没有使用NEW_TASK标志,因为我在Activity类之外开始活动.
现在有以下解决方案我可以想到但不确定哪一个最好基于架构观点.
1. ViewModel,其方法采用Activity参数并从片段中调用该方法
public startMyActivity(Activity activity){
activity.startActivity(new Intent(activity, MyActivity.class));
}
Run Code Online (Sandbox Code Playgroud)
现在在片段中添加类似这样的列表器
mBinding.myButton.setOnClickListener(){
viewModel.startMyActivity(getActivity());
}
Run Code Online (Sandbox Code Playgroud)
2.向intent添加一个New Task标志并将其保存在ViewModel本身中
Intent myIntent = new Intent(view.getContext(), MyActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
getApplication().startActivity(myIntent);
Run Code Online (Sandbox Code Playgroud)
3.从片段本身启动Activity
mBinding.myButton.setOnClickListener(){
activity.startActivity(new Intent(activity, MyActivity.class));
}
Run Code Online (Sandbox Code Playgroud)
我相信所有这些方法都很好,但是一个问题
是否可以在Fragment中分别使用绑定的ViewModel从view xml调用方法?
我不确定第二种方法,如果这仍然会在某些操作系统中崩溃应用程序.
从架构的角度和单元测试的角度来看哪一个是最好的方法?
我发现了一个不保留架构组件ViewModel的情况 - 简而言之,如下所示:
ViewModel调用ViewModel的方法并创建新对象在这种情况下,我的ViewModel实例正在被销毁,这是Android的正常行为吗?如果是这样,是否有任何建议的解决方案来保持其状态?
我可以想到的一种方法ViewModel是在调用时保存它,但是,只要活动实际完成,它也会保持状态.另一种方法可能是利用onCleared它,但它在每个屏幕旋转时触发(不仅如果应用程序在后台).
处理这种情况的银弹?
在实施架构组件方面是否有改进的余地,或者通常考虑:
1)注意:如果您选择使用AuthStateListener,请确保在启动FirebaseUI流之前取消注册,并在流返回后重新注册它.FirebaseUI在内部执行auth操作,这可能会在流程完成之前触发侦听器.
LiveData
public class FirebaseAuthLiveData extends LiveData<FirebaseUser> {
private FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
private FirebaseAuth.AuthStateListener authStateListener =
new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
setValue(firebaseUser);
}
};
@Override
protected void onActive() {
super.onActive();
firebaseAuth.addAuthStateListener(authStateListener);
}
@Override
protected void onInactive() {
super.onInactive();
firebaseAuth.removeAuthStateListener(authStateListener);
}
}
Run Code Online (Sandbox Code Playgroud)
视图模型
public class FirebaseAuthViewModel extends ViewModel {
private final FirebaseAuthLiveData firebaseAuthLiveData = new
FirebaseAuthLiveData();
public LiveData<FirebaseUser> getFirebaseAuthLiveData() {
return firebaseAuthLiveData; }
}
}
Run Code Online (Sandbox Code Playgroud)
ManiActivity
@Override
protected …Run Code Online (Sandbox Code Playgroud) firebase firebase-authentication android-livedata android-viewmodel
我尝试在MV活动中应用MVVM模式(我是Android菜鸟)。
我将Room与RxJava 2一起使用,例如,这是我的存储库中方法的签名:
public Single<MissionTask> getMissionTaskByID(long id) {..}
Run Code Online (Sandbox Code Playgroud)
在我的ViewModel类中,我对存储库和代码有如下引用:
private void doSomethingOnUserEvent() {
...
missionTaskRepository.getMissionTaskByID(firstID).
observeOn(AndroidSchedulers.mainThread()).
subscribeOn(Schedulers.io()).
subscribe(missionTask ->
{
// do some work and update live data
},
t -> {
// handle error
});
...
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切似乎都很好。现在- subscribe返回Disposable。
我的问题是:
在我经历的一些示例中,没有处理Disposable。
更新:我已经在android-architecture-components中看到了复合一次性材料的用法。
谢谢。
我正在将用户信息存储在本地会议室数据库中。在活动和片段中,我使用AndroidViewModel和LiveData侦听对数据库所做的更改并更新UI。
现在,我想分析所有过去的用户数据,以便为将来的决策提供建议。我的建议会针对用户对数据库所做的每一次更改而更改,因此我需要经常更新自己的建议,同时一遍又一遍地执行相同的计算。
我当时正在考虑在应用程序启动时启动一项服务,该服务通过ViewModel和LiveData侦听数据库更改并更新我的建议(这些建议也存储在同一数据库中)。但是某种方式服务不能
viewModel = ViewModelProviders.of(this).get(DataViewModel.class);基本上,每次数据库内容更改时,我只需要从数据库中读取所有条目,分析数据并更新5-10个值即可。
如果不在服务中,我应该如何以及在哪里进行计算?也许我陷入了一个错误的想法,而服务却不是正确的方法,因此非常感谢您提供有关如何执行此操作的任何想法!
题
双向数据绑定允许您使用来自对象的数据自动填充UI组件,然后在用户编辑这些UI组件时自动更新对象。
当用户编辑UI组件时,是否有一种方法不仅可以自动更新内存中的对象,还可以自动更新/将对象保留在Room数据库中?
我可以手动收听每个UI字段的修改,然后将对象手动保存到Room数据库。但是,这种手动的蛮力方法会否定我希望利用的双向数据绑定的好处。
语境
我的应用程序使用Android的Room Persistence Library将项目存储在SQLite数据库中。这是我的物品的简化版本:
@Entity
public class Item {
@PrimaryKey(autoGenerate = true)
private long id;
private String name;
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
ViewModel,LiveData和双向数据绑定的魔力使我的ItemEditorFragment可以自动使用所选项目中的数据填充UI,并在用户编辑UI组件时更新该项目:
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof ItemViewModelProvider) {
final ItemViewModelProvider itemViewModelProvider = (ItemViewModelProvider) context;
mViewModel = itemViewModelProvider.getItemViewModel();
} else { …Run Code Online (Sandbox Code Playgroud) android-databinding android-room android-livedata android-viewmodel
我正在使用android viewmodel,但是无法传递和访问来自另一个活动的活动viewmodel的数据。我只能用片段来做到这一点。
是否应该使用EventBus之类的库在很少的活动之间共享数据?
最好的做法是什么?
我尝试使用 Hilt codelab https://codelabs.developers.google.com/codelabs/android-hilt#10
它与 Activity 和 Fragment 配合良好
记录器是 RoomDB
然后我尝试用这篇文章将记录器注入到 viewModel 中
通过添加
implementation "androidx.hilt:hilt-lifecycle-viewmodel
:1.0.0-alpha02"
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
Run Code Online (Sandbox Code Playgroud)
查看模型代码
class RecordFragmentViewModel @ViewModelInject constructor(@Assisted private val savedStateHandle: SavedStateHandle) :
ViewModel() {
@DatabaseLogger
@Inject
lateinit var logger: LoggerDataSource
Run Code Online (Sandbox Code Playgroud)
要注入的类记录器
class LoggerLocalDataSource
@Inject constructor(private val logDao: LogDao) : LoggerDataSource {
Run Code Online (Sandbox Code Playgroud)
日志记录模块
@Qualifier
annotation class InMemoryLogger
@Qualifier
annotation class DatabaseLogger
@InstallIn(ApplicationComponent::class)
@Module
abstract class LoggingDatabaseModule {
@DatabaseLogger
@Singleton
@Binds
abstract fun bindDatabaseLogger(impl: LoggerLocalDataSource): LoggerDataSource
}
@InstallIn(ActivityComponent::class)
@Module
abstract class LoggingInMemoryModule { …Run Code Online (Sandbox Code Playgroud) android ×8
android-architecture-components ×3
android-room ×3
mvvm ×3
android-architecture-lifecycle ×1
android-mvvm ×1
dagger-hilt ×1
firebase ×1
java ×1
rx-java2 ×1