Android在MVVM Resarlt中从何处开始活动

问题描述

我应该在数据存储库中使用MVVM模式。数据来自Web Api调用。并根据数据,应用程序使用返回的URL启动Web浏览器。

  1. 关于用户交互,活动调用拥有数据的viewmodel:

CheckOutActivity.java:

MaterialRippleLayout makeOrder = findViewById(R.id.btn_make_order);
    makeOrder.setonClickListener(view ->{
        viewmodel.makeOrder();
    });
  1. viewmodel调用具有适当数据(OptionalShippingEntityIds)的DataRepository来调用Web Api异步:

CheckOutviewmodel.java

public void makeOrder(){
    cartRepository.makeOrder(optionalShippingEntityIds.getValue());
}

存储库之前已实例化:

public CheckOutviewmodel(@NonNull Application application) {
    super(application);
    cartRepository = new CartRepository(application);
}  
  1. 在DataRepository Api调用中执行:

CartRepository

public void makeOrder(ArrayList<Integer> optionalShippingEntityIds){
    HashMap<String,String> map = new HashMap<String,String>();
    String  idsstring=optionalShippingEntityIds.toString();
    map.put("shipment_saleitem_id",idsstring);
    rest.httpRequest(RestAdapter.HttpVerb.POST,"order",map,new makeOrderHandler());
}

CartRepository构造函数

private RestAdapter rest;
private Context context;

public CartRepository(Context context) {
    this.context = context;
    rest = RestAdapter.getInstance(context);
    version.setValue(0);
}

4.HttpResponseHandler处理 Web浏览器打开的URL Toast失败消息

CartRepository.java

class makeOrderHandler extends JsonHttpResponseHandler{
    @Override
    public void onSuccess(int statusCode,Header[] headers,JSONObject response) {
        if(statusCode == 200){
            try {
                Toast.makeText(context,"order number "+response.getInt("order_id")+"has been created",Toast.LENGTH_SHORT).show();
                String redirectUrl = response.getString("init_payment_url");
                version.setValue(version.getValue() +1);

                final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse(redirectUrl));
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                        context.startActivity(intent);
                        ((Activity)context).finishAffinity();
                        //System.exit(0);

                        /*Intent chooserIntent = Intent.createChooser(intent,"Open With");
                        chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        context.startActivity(chooserIntent);*/
                    }
                },2000);
            } catch (JSONException e) {
                Toast.makeText(context,"JSON parse error"+" : "+response.toString(),Toast.LENGTH_SHORT).show();
                e.printstacktrace();
            }
        }else{
            Log.e("server api changed ","error in getting response using kNown api \n" + response.toString());
            Toast.makeText(context,"api change",Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onFailure(int statusCode,String res,Throwable t) {
        // called when response HTTP status is "4XX" (eg. 401,403,404)
        Log.e("server 500","error in getting response using async-apache-http call"+" : "+res);
        t.printstacktrace();
        Toast.makeText(context,"خطا سرور ",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onFailure(int statusCode,Throwable t,JSONObject e) {
        if(statusCode == 504){
            Toast.makeText(context,"The Order hasnt been created duo to internal problem. please try again",Toast.LENGTH_SHORT).show();
        }else{
            Log.e("server api changed","error in getting response using kNown api \n" + e.toString());
            t.printstacktrace();
            Toast.makeText(context,"Api is unkNown",Toast.LENGTH_SHORT).show();
        }
    }
}

问题出在我在某些设备的线路((Activity)context).finishAffinity();中启动应用程序后,由于context应用程序上下文实例而不是活动上下文实例

  • 如果我通过viewmodel传递Activity实例,那我就违反了MVVM。
  • 如果我在The Activity中创建一个接口并实现它。它违反了活动单一职责(数据存储库响应处理程序应处理startActivity)
    所以我不知道该怎么处理。
  • 如果我消除了viewmodel的makeOrder,并使用 Activity Context 来构建存储库,我认为它的viewmodel负责处理数据操作工作。

....

因此,我对正确处理StartActivity和Toast的正确解决方案感到困惑。

如果有人可以通过正确的设计模式来帮助我,

解决方法

您的视图模型可以从AndroidViewModel扩展。 从文档: “了解应用程序上下文的ViewModel。

子类必须具有一个接受Application作为唯一参数的构造函数。”