如何在Java中使用androidx.lifecycle.ViewModelProvider

huangapple go评论118阅读模式
英文:

How to use the androidx.lifecycle.ViewModelProvider in Java

问题

我最近在学习关于架构组件的内容,正在按照旧教程使用旧方法进行操作:

  1. mainActivityViewModel =
  2. new ViewModelProvider(this).get(MainActivityViewModel.class);

但在ViewModelProvider的文档中,唯一可用的构造函数是:

  1. ViewModelProvider(ViewModelStoreOwner, Factory) ViewModelProvider(ViewModelStore, Factory)

所以我尝试了以下方法,但不确定在重写的方法中应该返回什么,它目前返回null,导致程序崩溃。

  1. public class MainActivity extends AppCompatActivity {
  2. private NoteViewModel noteViewModel;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. noteViewModel = new ViewModelProvider(this, new ViewModelProvider.Factory() {
  8. @NonNull
  9. @Override
  10. public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
  11. return null;
  12. }
  13. }).get(NoteViewModel.class);
  14. noteViewModel.getAllNotes().observe(this, new Observer<List<NoteEntity>>() {
  15. @Override
  16. public void onChanged(List<NoteEntity> noteEntities) {
  17. Toast.makeText(MainActivity.this,"Changed",Toast.LENGTH_LONG).show();
  18. }
  19. });
  20. }
  21. }

我的方法是否正确?我现在完全迷失了。我应该从重写的方法中返回什么?

英文:

I'm recently learning about the architectural components and was following the old tutorial where they used the old method:
<!-- language-all: java -->

  1. mainActivityViewModel =
  2. new ViewModelProvider(this).get(MainActivityViewModel.class);

But in the documentation for the ViewModelProvider, the only constructors available are
ViewModelProvider(ViewModelStoreOwner, Factory) &
ViewModelProvider(ViewModelStore, Factory).

So I did something like this but I'm not sure what to do in the overridden method and it currently returns null that crashes the program.

  1. public class MainActivity extends AppCompatActivity {
  2. private NoteViewModel noteViewModel;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. noteViewModel = new ViewModelProvider(this, new ViewModelProvider.Factory() {
  8. @NonNull
  9. @Override
  10. public &lt;T extends ViewModel&gt; T create(@NonNull Class&lt;T&gt; modelClass) {
  11. return null;
  12. }
  13. }).get(NoteViewModel.class);
  14. noteViewModel.getAllNotes().observe(this, new Observer&lt;List&lt;NoteEntity&gt;&gt;() {
  15. @Override
  16. public void onChanged(List&lt;NoteEntity&gt; noteEntities) {
  17. Toast.makeText(MainActivity.this,&quot;Changed&quot;,Toast.LENGTH_LONG).show();
  18. }
  19. });
  20. }
  21. }

Is my approach correct? I'm absolutely lost right now. What am I supposed to return from the overridden method?

答案1

得分: 2

noteViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(NoteViewModel.class);

当我们在 ViewModel 的构造函数中传递参数时(除了 Application 参数),我们使用自定义的工厂。

在 Gradle 依赖中添加以下代码:

  1. def lifecycle_version = "2.2.0"
  2. // LiveData
  3. implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
  4. //
  5. implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
  6. // ViewModel
  7. implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
英文:

Use this

  1. noteViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(NoteViewModel.class;

We use custom factory, when we pass param to the constructor of ViewModel (apart from Application param).

and gradle dependency in case,

  1. def lifecycle_version = &quot;2.2.0&quot;
  2. // LiveData
  3. implementation &quot;androidx.lifecycle:lifecycle-livedata:$lifecycle_version&quot;
  4. //
  5. implementation &quot;androidx.lifecycle:lifecycle-common-java8:$lifecycle_version&quot;
  6. // ViewModel
  7. implementation &quot;androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version&quot;

答案2

得分: 1

首先,您需要在活动类中初始化 ViewModel,如下所示:

  1. noteViewModel = ViewModelProvider(this).get(NoteViewModel.class);

NoteViewModel.java 中:

您需要为存储模型提供的更新数据定义 LiveData 变量,并将其更新传递到 ViewModel。

  1. public class NoteViewModel extends AndroidViewModel {
  2. AppRepository appRepository;
  3. MediatorLiveData<List<NoteEntity>> mediatorData;
  4. public NoteViewModel (@NonNull Application application) {
  5. super(application);
  6. mediatorData = new MediatorLiveData<>();
  7. appRepository = new AppRepository(MyApplication.apiService, application.retrofit);
  8. }
  9. public MediatorLiveData<List<NoteEntity>> getMediatorLiveData() {
  10. return mediatorData;
  11. }
  12. public void getNoteEntry() {
  13. try {
  14. mediatorData.addSource(appRepository.getNoteEntry(), new Observer<List<NoteEntity>>() {
  15. @Override
  16. public void onChanged(@Nullable List<NoteEntity> data) {
  17. mediatorData.postValue(data);
  18. }
  19. });
  20. } catch (Exception e) {
  21. }
  22. }
  23. }

MainActivityonCreate() 方法中,注册观察者并从 ViewModel 调用 API:

  1. noteViewModel.getMediatorLiveData().observe(this, new Observer<List<NoteEntity>>() {
  2. @Override
  3. public void onChanged(List<NoteEntity> noteEntities) {
  4. Toast.makeText(MainActivity.this, "Changed", Toast.LENGTH_LONG).show();
  5. }
  6. });
  7. noteViewModel.getNoteEntry();

AppRepository.java 文件如下:

  1. class AppRepository() {
  2. ApiService apiService;
  3. Retrofit retrofit;
  4. public AppRepository(ApiService apiService, Retrofit retrofit) {
  5. this.apiService = apiService;
  6. this.retrofit = retrofit;
  7. }
  8. public MediatorLiveData<List<NoteEntity>> getNotes() {
  9. MediatorLiveData<List<NoteEntity>> data = new MediatorLiveData<List<NoteEntity>>();
  10. apiService.getNotes().enqueue(new Callback<List<NoteEntity>>() {
  11. @Override
  12. void onResponse(Call<List<NoteEntity>> call, Response<List<NoteEntity>> response) {
  13. if (response.isSuccessful()) {
  14. if (response.body() != null) {
  15. data.postValue(response.body()); //成功数据
  16. } else {
  17. data.postValue(null); //错误
  18. }
  19. } else {
  20. data.postValue(null); //错误
  21. }
  22. }
  23. @Override
  24. void onFailure(Call<List<NoteEntity>> call, Throwable t) {
  25. data.postValue(null); //错误
  26. }
  27. });
  28. return data;
  29. }
  30. }
英文:

First you need to initialize viewmodel in activity class like :

  1. noteViewModel = ViewModelProvider(this).get(NoteViewModel.class);

In NoteViewModel.java

You need to define livedata variable for storing updated data provided by model and update post to view model

NoteViewModel.java file look like :

  1. public class NoteViewModel extends AndroidViewModel {
  2. AppRepository appRepository;
  3. MediatorLiveData&lt;List&lt;NoteEntity&gt;&gt; mediatorData;
  4. public NoteViewModel (@NonNull Application application) {
  5. super(application);
  6. mediatorData=new MediatorLiveData&lt;&gt;();
  7. appRepository=new AppRepository((MyApplication).apiService, application.retrofit);
  8. }
  9. public MediatorLiveData&lt;List&lt;NoteEntity&gt;&gt; getMediatorLiveData() {
  10. return mediatorVideoData;
  11. }
  12. public void getNoteEntry()
  13. {
  14. try {
  15. mediatorData.addSource(appRepository.getNoteEntry(), new Observer&lt;List&lt;NoteEntity&gt;&gt;() {
  16. @Override
  17. public void onChanged(@Nullable List&lt;NoteEntity&gt; data) {
  18. mediatorData.postValue(data);
  19. }
  20. });
  21. }catch (Exception e)
  22. {
  23. }
  24. }
  25. }

In onCreate() of Mainactivity register observer like and call the API from view model like

  1. noteViewModel.getMediatorLiveData().observe(this, new Observer&lt;List&lt;NoteEntity&gt;&gt;() {
  2. @Override
  3. public void onChanged(List&lt;NoteEntity&gt; noteEntities) {
  4. Toast.makeText(MainActivity.this,&quot;Changed&quot;,Toast.LENGTH_LONG).show();
  5. }
  6. });
  7. noteViewModel.getNoteEntry();

AppRepository.java file look like

  1. class AppRepository() {
  2. ApiService apiService;
  3. Retrofit retrofit;
  4. public AppRepository(ApiService apiService ,Retrofit retrofit){
  5. this.apiService = apiService;
  6. this.retrofit = retrofit;
  7. }
  8. public MediatorLiveData&lt;List&lt;NoteEntity&gt;&gt; getNotes() {
  9. MediatorLiveData&lt;List&lt;NoteEntity&gt;&gt; data = new MediatorLiveData&lt;List&lt;NoteEntity&gt;&gt;()
  10. apiService.getNotes()
  11. .enqueue(new Callback&lt;List&lt;NoteEntity&gt;&gt; {
  12. @Override
  13. void onResponse(
  14. Call&lt;List&lt;NoteEntity&gt;&gt; call,
  15. Response&lt;List&lt;NoteEntity&gt;&gt; response
  16. ) {
  17. if (response.isSuccessful()) {
  18. if(response.body()!=null){
  19. data.postValue(response.body()); //successfull data
  20. }else{
  21. data.postValue(null); //error
  22. }
  23. } else {
  24. data.postValue(null); //error
  25. }
  26. }
  27. @Override
  28. fun onFailure(
  29. Call&lt;List&lt;NoteEntity&gt;&gt; call,
  30. Throwable t
  31. ) {
  32. data.postValue(null); //error
  33. }
  34. })
  35. return data;
  36. }
  37. }

答案3

得分: 1

  1. Kotlin 代码。
  2. build.gradle 中添加
  3. implementation "androidx.activity:activity-ktx:1.1.0"
  4. 然后
  5. val noteViewModel by viewModels<NoteViewModel>()
英文:

Kotlin Code.

In build.gradle add

  1. implementation &quot;androidx.activity:activity-ktx:1.1.0&quot;

then

  1. val noteViewModel by viewModels&lt;NoteViewModel&gt;()

答案4

得分: 0

找到了解决方法,经过4个小时的研究。

  1. noteViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(NoteViewModel.class);

另外,这些依赖项应该添加到 gradle 文件中。

  1. def room_version = "2.2.5";
  2. def lifecycle_version = "2.2.0";
  3. implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
  4. // LiveData
  5. implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
  6. annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
  7. implementation "androidx.room:room-runtime:$room_version"
  8. annotationProcessor "androidx.room:room-compiler:$room_version"

不确定错误是否是因为我漏掉了注解依赖,但现在一切都正常工作了。

英文:

Figured it out after 4 hours.

  1. noteViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(NoteViewModel.class);

Also these dependencies should be added to the gradle file.

  1. def room_version = &quot;2.2.5&quot;
  2. def lifecycle_version = &quot;2.2.0&quot;
  3. implementation &quot;androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version&quot;
  4. // LiveData
  5. implementation &quot;androidx.lifecycle:lifecycle-livedata:$lifecycle_version&quot;
  6. annotationProcessor &quot;androidx.lifecycle:lifecycle-compiler:$lifecycle_version&quot;
  7. implementation &quot;androidx.room:room-runtime:$room_version&quot;
  8. annotationProcessor &quot;androidx.room:room-compiler:$room_version&quot;

Not sure if the error was caused because I missed the annotation dependency. But everything works now.

huangapple
  • 本文由 发表于 2020年8月24日 14:24:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/63555733.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定