问题描述
我应该在数据存储库中使用MVVM模式。数据来自Web Api调用。并根据数据,应用程序使用返回的URL启动Web浏览器。
CheckOutActivity.java:
MaterialRippleLayout makeOrder = findViewById(R.id.btn_make_order);
makeOrder.setonClickListener(view ->{
viewmodel.makeOrder();
});
CheckOutviewmodel.java
public void makeOrder(){
cartRepository.makeOrder(optionalShippingEntityIds.getValue());
}
存储库之前已实例化:
public CheckOutviewmodel(@NonNull Application application) {
super(application);
cartRepository = new CartRepository(application);
}
- 在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作为唯一参数的构造函数。”