1

所以,我剛開始用LiveData嘗試 - 我忙着一個新的項目,在這裏我使用ViewModel以及LiveData - 與一些RESTFul服務我用的取數據,他們不參數並返回一些數據。製作到LiveData更改爲「重做」工作視圖模型

的MVVM模式與LiveData典型的設置看起來像這樣:

public class MyActivity extends AppCompatActivity { 
    public void onCreate(Bundle savedInstanceState) { 
     MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class); 
     model.getUsers().observe(this, users -> { 
      // update UI 
     }); 
    } 
} 

現在,當我們離開這個活動,並進入到一個新的活動,通過使用意圖或其他方式,而不是按下後退按鈕(因此,不會調用finalize) - 然後回到MyActivity - 我們當然不會再次獲取users,因爲我們仍然應該擁有該數據。

但是,如果我們想要再次獲取它們呢?

這樣做不好,從我看的唯一方法,似乎叫「的setValue」的getUsers()LiveData對象

事情是這樣的:

public class MyActivity extends AppCompatActivity { 
    public void onResume() { 
    viewModel.setActive(true); 
    } 
} 

而且ViewModel看起來像這樣:

private final MutableLiveData<Boolean> activeLiveData = new MutableLiveData<>(); 

ViewModel(ViewModelRepo repo){ 
     this.repo = repo; 

     results = Transformations.switchMap(activeLiveData, active ->{ 
     if(active){ 
      return repo.getUsers(); 
     }else { 
      return AbsentLiveData.create(); //"Null live data" 
     } 
     }); 
    } 

    LiveData<Users>> getUsers() { 
    return results; 
    } 

//This could be called "update" with no params 
    void setActive(boolean active) { 
    activeLiveData.setValue(active); 
    } 

我決定這樣做的一個原因是因爲Google不希望我們這樣做:

class MyViewModel extends ViewModel { 
    private final PostalCodeRepository repository; 
    public MyViewModel(PostalCodeRepository repository) { 
     this.repository = repository; 
    } 

    private LiveData<String> getPostalCode(String address) { 
     // DON'T DO THIS 
     return repository.getPostCode(address); 
    } 
} 

出於這個原因:

如果是這樣的實現,用戶界面將需要從 註銷以前的LiveData每次 他們稱之爲getPostalCode重新註冊到新的實例( )。此外,如果UI被重新創建,則 將觸發對repository.getPostCode()的另一次調用,而不是使用前一個調用的結果 。

有沒有更好的方法讓ViewModel「重做」它的repo.getUsers()調用?也許我可以做一個方法,說「更新()」,而不是「主動」,但仍然 - 它以不同的方式做同樣的事情。

回答

1

那麼在這裏,您正在執行ViewModel的創建者的提取操作,該操作將事物鎖定到位。通常他們會建議在獲取器中獲取數據,如果數據不存在的話。

所以一個好的選擇是使用常規模式第一:

private MutableLiveData<Users> users = null; 

ViewModel(ViewModelRepo repo){ 
     this.repo = repo; 
    } 

    LiveData<Users> getUsers() { 
    if (users = null) { 
     fetchUsers(); 
    } 
    return users; 
    } 

    public void fetchUsers() { 
    users.postValue(repo.getUsers()); 
    } 

,然後從活動/碎片,每當你覺得需要「刷新用戶」,你只需撥打viewModel.fetchUsers();