在尝试引用我的viewmodel类中的片段时遇到了一些问题。这是我的片段称为视图模型的部分:
@Click(R.id.buttonExport)
void buttonExportClicked(View v){
SummaryViewModel summaryViewModel = ViewModelProviders.of(this).get(SummaryViewModel.class);
summaryViewModel.export(webViewResult);
}
在我试图访问上下文和活动的视图模型中:
public void exportSelfTestSummary(WebView webViewResult) {
Activity context = (Activity) getApplication().getApplicationContext();
final ProgressDialog progressDialog=new ProgressDialog(context);
progressDialog.show();
PdfView.createWebPrintJob(context, webViewResult, directory, fileName, new PdfView.Callback() {
....
}
以及我收到的错误消息:
07-02 02:34:01.922 3563-3563/com.mainapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mainapp, PID: 3563
java.lang.ClassCastException: com.mainapp.App cannot be cast to android.app.Activity
at com.mainapp.viewmodel.SummaryViewModel.export(SummaryViewModel.java:218)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
有什么想法吗?谢谢!
修改
@Inject
public SummaryViewModel(@NonNull Application application) {
super(application);
}
答案 0 :(得分:0)
该错误表明已足够清楚,您无法将Application
强制转换为Activity
您正在做的是获取应用程序上下文,它将返回一个Application
类:
Activity context = (Activity) getApplication().getApplicationContext();
如果您位于片段中,只需使用fragment.getActivity()
答案 1 :(得分:0)
由于尝试将应用程序强制转换为Activity,所以您收到ClassCastException。
Activity context = (Activity) getApplication().getApplicationContext();
getApplication()方法返回App类,getApplicationContext()方法也返回,该方法不能用于获取Activity。
永远不要在ViewModel中使用对Activity或Fragment的引用。绝对不要从ViewModel修改UI。 ViewModel应该只包含用于修改UI的数据。
例如:
片段/活动:
SummaryViewModel summaryViewModel = ViewModelProviders.of(this).get(SummaryViewModel.class);
LiveData<WebResult> data = summaryViewModel.getWebViewDataInBackgroundThread();
//observe on this data for changes in your activity/fragment
data.observe(this, Observer {
@Override
public void onChanged(@Nullable final WebResult result) {
// Update the UI,
Activity context = (Activity) getApplication().getApplicationContext();
final ProgressDialog progressDialog=new ProgressDialog(context);
progressDialog.show();
PdfView.createWebPrintJob(context, webViewResult, directory, fileName, new PdfView.Callback() {
....
}
})
在您的ViewModel中:
public LiveData<WebResult> getWebViewDataInBackgroundThread() {
// getdata and return as LiveData
}
答案 2 :(得分:0)
使用Context
和与活动生命周期相关的人员专门查看ViewModel
内是一个好习惯。 ViewModel
将仅保存数据并在数据和视图之间建立连接。在ProgressDialog
或Activity
中创建Fragment
。使用ViewModel
作为您的业务逻辑。在LiveData
中为ProgressDialog
状态创建一个ViewModle
。更改LiveData
的值并在Activity
或Fragment
中观察它。因此,您可以决定何时显示ProgressDialog
或何时隐藏它。您的视图位于Activity
或Fragment
内部,并且没有MemoryLeak的可能性。
正如@ tam-huynh提到的那样,您的问题是您试图将Application Context强制转换为无效的Activity
。
在LiveData
中创建ViewModel
private MutableLiveData<Integer> progressDialogState;
public LiveData<Integer> getProgressDialogStateAsObservable(){
return progressDialogState;
}
public void setProgressDialogState(int value){
progressDialogState.setValue(value);
}
public void exportSelfTestSummary(WebView webViewResult) {
//Activity context = (Activity) getApplication().getApplicationContext();
//final ProgressDialog progressDialog=new ProgressDialog(context);
//progressDialog.show();
setProgressDialogState(1)
PdfView.createWebPrintJob(context, webViewResult, directory, fileName, new PdfView.Callback() {
....
// after work done set value to 0
//setProgressDialogState(0)
}
在Activity
或Fragment
中观察
viewModel.getProgressDialogStateAsObservable().observe(getActivity(), state -> {
if (state == 1) {
// .....
// show
}else if(state == 0){
// hide
}
});
答案 3 :(得分:0)
或者,您也可以通过父视图来访问“活动”:
Activity act = (Activity) webViewResult.getParent().getParent().....so on