我在这里遵循这个指南,https://developer.android.com/jetpack/docs/guide?hl=en
为了学习关注点的分离,我创建了一个简单的应用程序,它从API中获取一些数据并在活动中显示在屏幕上。
我的活动如下,其职责是向用户显示信息。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button myButt;
private MainViewModel mvw;
private TextView myView;
private MutableLiveData<Orders> mld;
@Override
protected void onCreate(Bundle savedInstanceState) {
mvw = new ViewModelProvider(this).get(MainViewModel.class);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButt = findViewById(R.id.button);
myView = findViewById(R.id.textview);
myButt.setOnClickListener(this);
mvw.getMld().observe(this, new Observer<Orders>() {
@Override
public void onChanged(Orders orders) {
Log.i("livedata","got an updt");
myView.setText(mvw.extractDate(orders));
}
});
}
@Override
public void onClick(View view) {
switch(view.getId()){
case R.id.button:
Log.i("tag","hello");
mvw.updateData();
}
}
}下面遵循ViewModel,它关心的是从存储库类中获取数据,并在活动中显示数据之前对这些数据进行一些计算。
public class MainViewModel extends ViewModel {
private GetOrder getOrderRepo;
private MutableLiveData<Orders> mld;
public MainViewModel(){
getOrderRepo = new GetOrder();
mld = getOrderRepo.getAllOrders();
}
public MutableLiveData<Orders> getMld() {
return mld;
}
public void setMld(MutableLiveData<Orders> mld) {
this.mld = mld;
}
public void updateData(){
getOrderRepo.getAllOrders(); //discard the return value
}
public String extractDate(Orders orders){
ArrayList<Order> listOfOrders = orders.getOrders();
String date = listOfOrders.get(0).getOrderTime();
return date;
}
}接下来是存储库,它处理来自API的GET请求,并将其放入MutableLiveData容器"allOrders“中。
public class GetOrder {
private ApiService mAPIService;
MutableLiveData<Orders> allOrders;
private Orders orders;
public GetOrder(){
mAPIService = ApiUtils.getAPIService();
}
public MutableLiveData<Orders> getAllOrders(){
Log.i("func","starting func");
allOrders = new MutableLiveData<Orders>();
mAPIService.getOrders().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Orders>() {
@Override
public void onCompleted() {
Log.i("func","onComplete");
}
@Override
public void onError(Throwable e) {
Log.i("onError",e.toString());
}
@Override
public void onNext(Orders orders) {
Log.i("Repo",orders.toString());
allOrders.setValue(orders);
}
});
return allOrders;
}
}这是一个正确的实现吗?还是我误解了什么?
我需要考虑的一个问题是按钮具有mvw.orderData().observe(这个,新的观察者()),因为这每次都会创建一个新的观察者。还是在每个onChanged之后就死了?
反馈后更新
发布于 2020-03-08 13:24:18
您在这里实现的是MVVM架构。模型(存储库)-View(活动)-VM(视图模型)。基本结构看起来不错,但我看到了一些可以改进的地方,以便更好地遵循最佳实践。
更新(2):检查此链接下的MainActivityViewModel。您在MutableLiveData中设置的ViewModel应该是私有的。
private MutableLiveData<List<String>> fruitList;然后通过普通的MutableLiveData返回该LiveData。这个LiveData是不可变的,不能是空的,因此可以安全地向您的MainActivity这样的类公开,在那里您可以观察到它。
LiveData<List<String>> getFruitList() {
if (fruitList == null) {
fruitList = new MutableLiveData<>();
loadFruits();
}
return fruitList;
} 在您的示例中,loadFruits()函数将是存储库中的api调用。
现在它已经意识到生命周期了。如果您愿意的话,以后可以在片段中插入相同的实例。
发布于 2020-03-08 13:10:59
ViewModel应该负责数据的存储。
因此,更好的方法是将MutableLiveData<Orders> allOrders;放在ViewModel中而不是存储库中。这样,Repository只负责获取数据。它不应该储存它。
然后,在您的活动中,您应该观察allOrders实时数据,如:mvw.allOrders.observe(...) in onCreate()。
在单击按钮时,只需调用Repository方法,使用ViewModel的方法allOrders LiveData获取/更新orderData()。
https://stackoverflow.com/questions/60587662
复制相似问题