Android ClassCastException 通过在视图模型中引用片段



我在尝试引用视图模型类中的片段时遇到了一些问题。这是我的片段调用视图模型的部分:

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

错误说得很清楚,你不能Application投射到Activity

您正在做的是获取应用程序上下文,它将返回一个Application类:

Activity context = (Activity) getApplication().getApplicationContext();

如果您在片段内,只需使用fragment.getActivity()

您正在获得 ClassCastException,因为您正在尝试将应用程序强制转换为 Activity。

Activity context = (Activity) getApplication().getApplicationContext();

getApplication(( 方法返回 App 类,getApplicationContext(( 方法也返回,该方法不能用于获取 Activity。

切勿在视图模型中使用对活动或片段的引用。永远不应从视图模型修改您的 UI。视图模型应仅包含用于修改 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() {
....
}
})

在您的视图模型中:

public LiveData<WebResult> getWebViewDataInBackgroundThread() {
// getdata and return as LiveData
}

阅读有关 LiveData 和 ViewModel 的更多信息

或者,您可以通过父视图访问活动挖掘:

Activity act = (Activity) webViewResult.getParent().getParent().....so on

使用Context和活动生命周期相关人员专门查看内部ViewModel不是一个好的做法。ViewModel只会保存数据并在数据和视图之间建立连接。在ActivityFragment中创建ProgressDialog。将ViewModel用于业务逻辑。在ViewModle中为ProgressDialog状态创建LiveData。更改LiveData值并在ActivityFragment中观察它。因此,您可以决定何时显示ProgressDialog或何时隐藏它。您的视图位于ActivityFragment内部,并且没有内存泄漏的可能性。

正如 @tam-huynh 提到的,您的问题是您试图将应用程序上下文强制转换为无效Activity

ViewModel中创建LiveData

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

ActivityFragment观察它

viewModel.getProgressDialogStateAsObservable().observe(getActivity(), state -> {
if (state == 1) {
// .....
// show  
}else if(state == 0){
// hide
}
});

从这里了解 Android 架构组件

相关内容

  • 没有找到相关文章

最新更新