标签: android-viewmodel

Android架构组件ViewModel - 与Service/IntentService的通信

我在探索谷歌的Android架构组件.在我的项目中,我依赖于ServicesIntentServices.从IntentService或Service 与app的ViewModel通信的正确方法是什么?使用LiveData可以实现吗?

android mvvm android-viewmodel android-architecture-components

6
推荐指数
1
解决办法
3329
查看次数

AndroidViewModel - 进行重复调用不会返回observe函数中的数据

我的问题与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

6
推荐指数
1
解决办法
3498
查看次数

从MVVM架构中的ViewModel启动Activity的最佳方法

我在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调用方法?

我不确定第二种方法,如果这仍然会在某些操作系统中崩溃应用程序.

从架构的角度和单元测试的角度来看哪一个是最好的方法?

android mvvm android-mvvm android-viewmodel

6
推荐指数
1
解决办法
3269
查看次数

Android ViewModel在屏幕旋转时重新创建

我发现了一个不保留架构组件ViewModel的情况 - 简而言之,如下所示:

  1. 活动已启动,并且已创建ViewModel实例
  2. 活动是背景
  3. 设备屏幕旋转
  4. 活动被放回到前台
  5. ViewModel调用ViewModel的方法并创建新对象

在这种情况下,我的ViewModel实例正在被销毁,这是Android的正常行为吗?如果是这样,是否有任何建议的解决方案来保持其状态?
我可以想到的一种方法ViewModel是在调用时保存它,但是,只要活动实际完成,它也会保持状态.另一种方法可能是利用onCleared它,但它在每个屏幕旋转时触发(不仅如果应用程序在后台).
处理这种情况的银弹?

android android-viewmodel android-architecture-components

6
推荐指数
1
解决办法
5308
查看次数

使用LiveData的FirebaseAuth.AuthStateListener.以下实施是否有改进余地?

在实施架构组件方面是否有改进的余地,或者通常考虑:

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

6
推荐指数
1
解决办法
855
查看次数

MVVM-使用RxJava和Room在ViewModel中处理Disposable-s

我尝试在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

我的问题是:

  1. 我应该如何处理一次性用品(例如,可以将其放入复合一次性用品中并在清除模型后将其丢弃)?
  2. 如果我不处理该怎么办?泄漏?为什么?

在我经历的一些示例中,没有处理Disposable。

更新:我已经在android-architecture-components中看到了复合一次性材料的用法。

谢谢。

android mvvm rx-java2 android-room android-viewmodel

6
推荐指数
1
解决办法
2124
查看次数

如何从服务中的Room数据库读取数据和侦听更改?

我正在将用户信息存储在本地会议室数据库中。在活动和片段中,我使用AndroidViewModel和LiveData侦听对数据库所做的更改并更新UI。

现在,我想分析所有过去的用户数据,以便为将来的决策提供建议。我的建议会针对用户对数据库所做的每一次更改而更改,因此我需要经常更新自己的建议,同时一遍又一遍地执行相同的计算。

我当时正在考虑在应用程序启动时启动一项服务,该服务通过ViewModel和LiveData侦听数据库更改并更新我的建议(这些建议也存储在同一数据库中)。但是某种方式服务不能

  1. 通过获取ViewModel viewModel = ViewModelProviders.of(this).get(DataViewModel.class);
  2. 观察LiveData对象,因为它不是LifecycleOwner。

基本上,每次数据库内容更改时,我只需要从数据库中读取所有条目,分析数据并更新5-10个值即可。

如果不在服务中,我应该如何以及在哪里进行计算?也许我陷入了一个错误的想法,而服务却不是正确的方法,因此非常感谢您提供有关如何执行此操作的任何想法!

java android android-service android-room android-viewmodel

6
推荐指数
2
解决办法
3498
查看次数

使用Room自动保留两种方式的数据绑定更改?

双向数据绑定允许您使用来自对象的数据自动填充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

6
推荐指数
1
解决办法
437
查看次数

viewmodel在活动之间共享数据

我正在使用android viewmodel,但是无法传递和访问来自另一个活动的活动viewmodel的数据。我只能用片段来做到这一点。

是否应该使用EventBus之类的库在很少的活动之间共享数据?

最好的做法是什么?

android android-viewmodel

6
推荐指数
0
解决办法
1665
查看次数

Android Hilt dagger 在 vi​​ewModel @ViewModelInject 中注入接口得到 UninitializedPropertyAccessException

我尝试使用 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 dependency-injection android-viewmodel dagger-hilt

6
推荐指数
1
解决办法
9005
查看次数