Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android应用程序架构我这样做是否正确?_Java_Android_Retrofit - Fatal编程技术网

Java Android应用程序架构我这样做是否正确?

Java Android应用程序架构我这样做是否正确?,java,android,retrofit,Java,Android,Retrofit,我在这里遵循这个指南 为了学习关注点分离,我创建了一个简单的应用程序,它从API获取一些数据,并在活动中显示在屏幕上 public class MainViewModel extends ViewModel { private GetOrder getOrderRepo; private MutableLiveData<Orders> mld; public MainViewModel(){ getOrderRepo = new GetOrd

我在这里遵循这个指南

为了学习关注点分离,我创建了一个简单的应用程序,它从API获取一些数据,并在活动中显示在屏幕上

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;
    }

}
我的活动如下:它的职责是向用户显示信息

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();
        }
    }
}
public类MainActivity扩展AppCompatActivity实现View.OnClickListener{
私人按钮;
私有主视图模型mvw;
私有文本视图myView;
私有可变livedata mld;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
mvw=新的ViewModelProvider(this.get)(MainViewModel.class);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButt=findViewById(R.id.按钮);
myView=findviewbyd(R.id.textview);
myButt.setOnClickListener(this);
mvw.getMld().observe(这个,新的观察者(){
@凌驾
更改后的公共作废(订单){
Log.i(“livedata”,“获得updt”);
setText(mvw.extractDate(orders));
}
});
}
@凌驾
公共void onClick(视图){
开关(view.getId()){
案例R.id按钮:
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;
    }

}
public类MainViewModel扩展了ViewModel{
私人GetOrder getOrderRepo;
私有可变livedata mld;
公共主视图模型(){
getOrderRepo=新的GetOrder();
mld=getOrderRepo.getAllOrders();
}
公共可变livedata getMld(){
返回mld;
}
公共void setMld(MutableLiveData mld){
this.mld=mld;
}
公共void updateData(){
getOrderRepo.getAllOrders();//放弃返回值
}
公共字符串提取日期(订单){
ArrayList listOfOrders=orders.getOrders();
字符串日期=listOfOrders.get(0.getOrderTime();
返回日期;
}
}
接下来是存储库,它处理来自API的GET请求,并将其放入MutableLiveData容器“allOrders”中

公共类GetOrder{
私人电话服务;
可变LiveData allOrders;
私人订单;
公共秩序(){
mAPIService=aputils.getAPIService();
}
公共可变LiveData getAllOrders(){
Log.i(“func”,“启动func”);
allOrders=new MutableLiveData();
mAPIService.getOrders().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(新订户(){
@凌驾
未完成的公共无效(){
Log.i(“func”、“onComplete”);
}
@凌驾
公共无效申报人(可丢弃的e){
Log.i(“onError”,例如toString());
}
@凌驾
公共无效onNext(订单){
Log.i(“Repo”,orders.toString());
allOrders.setValue(订单);
}
});
返回分配顺序;
}
}
这是正确的实现吗?还是我误解了什么

我关心的一个问题是按钮上有 mvw.orderData().observe(这是一个新的观察者(),因为它每次都会创建一个新的观察者。还是每次更改后它都会消失


反馈后更新

ViewModel应负责存储数据

因此,更好的方法是在ViewModel中使用
MutableLiveData allOrders;
,而不是存储库。这样,存储库只负责获取数据,而不应存储数据

然后,在您的活动中,您应该观察
allOrders
实时数据,例如:
mvw.allOrders.observe(…)
onCreate()


点击按钮,您只需调用Repository方法,即可使用ViewModel的方法获取/更新
allOrders
LiveData()

这里实现的是MVVM体系结构。模型(存储库)-视图(活动)-虚拟机(ViewModel).基本结构看起来不错,但我看到了一些可以改进的地方,以便更好地遵循最佳实践

  • 正如您所说,您正在为每个按钮单击创建一个新的观察者。 您应该改为在onCreate中观察LiveData。在ViewModel中添加一个函数,告诉存储库更新数据,并在onClick方法中调用该函数
  • 您应该将MutableLiveData实现为私有,并将其包装在LiveData中,然后在活动中观察。这样就不会发生变异。此外,ViewModel应该存储获取的MutableLiveData
  • 更新(2): 检查。在ViewModel中设置的可变LiveData应该是私有的

     private MutableLiveData<List<String>> fruitList;
    
    private MutableLiveData结果列表;
    
    然后通过普通LiveData返回该可变LiveData。该LiveData是不可变的,不能为null,因此可以安全地公开给其他类,如MainActivity,您可以在其中观察它

    LiveData<List<String>> getFruitList() {
            if (fruitList == null) {
                fruitList = new MutableLiveData<>();
                loadFruits();
            }
            return fruitList;
        } 
    
    LiveData获取结果列表(){
    如果(结果列表==null){
    结果列表=新的可变LiveData();
    装载水果();
    }
    返回结果列表;
    } 
    
    在您的情况下,loadFruits()函数将是来自存储库的api调用

  • 您应该使用ViewModelProvider和/或ViewModelFactory实例化ViewModel。这是一个更详细的解释。它应该如下所示:

    private val viewModel=ViewModelProvider(this).get(MainViewModel::class.java)

  • 它现在是生命周期感知的。如果您愿意,您可以稍后在片段中注入相同的实例

  • 只是为了好玩:我喜欢h