Java 通过引用viewmodel中的片段实现Android ClassCastException
我在尝试引用viewmodel类中的片段时遇到了一些问题。下面是我的片段调用viewmodel的部分:Java 通过引用viewmodel中的片段实现Android ClassCastException,java,android,fragment,viewmodel,Java,Android,Fragment,Viewmodel,我在尝试引用viewmodel类中的片段时遇到了一些问题。下面是我的片段调用viewmodel的部分: @Click(R.id.buttonExport) void buttonExportClicked(View v){ SummaryViewModel summaryViewModel = ViewModelProviders.of(this).get(SummaryViewModel.class); summaryViewModel.export(webViewResult
@Click(R.id.buttonExport)
void buttonExportClicked(View v){
SummaryViewModel summaryViewModel = ViewModelProviders.of(this).get(SummaryViewModel.class);
summaryViewModel.export(webViewResult);
}
在我尝试访问上下文和活动的viewmodel中:
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);
}
错误说明很清楚,您无法将
应用程序
强制转换为活动
您要做的是获取应用程序上下文,它将返回一个应用程序类:
Activity context = (Activity) getApplication().getApplicationContext();
如果您在片段中,只需使用fragment.getActivity()
就可以得到一个ClassCastException,因为您试图将应用程序强制转换为活动
Activity context = (Activity) getApplication().getApplicationContext();
getApplication()方法返回App类,getApplicationContext()方法也返回App类,该方法不能用于获取活动
Activity context = (Activity) getApplication().getApplicationContext();
您不应该在ViewModel中使用对活动或片段的引用。决不能从ViewModel修改UI。ViewModel应仅包含用于修改UI的数据
例如:
片段/活动:
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() {
....
}
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() {
....
}
})
SummaryViewModel SummaryViewModel=ViewModelProviders.of(this.get)(SummaryViewModel.class);
LiveData data=summaryViewModel.getWebViewDataInBackgroundThread();
//观察此数据,了解您的活动/片段的变化
观察(这个,观察者{
@凌驾
更改后的公共void(@Nullable final WebResult){
//更新用户界面,
活动上下文=(活动)getApplication().getApplicationContext();
final ProgressDialog ProgressDialog=新建ProgressDialog(上下文);
progressDialog.show();
createWebPrintJob(上下文、webViewResult、目录、文件名、新PdfView.Callback(){
....
}
})
在ViewModel中:
public LiveData<WebResult> getWebViewDataInBackgroundThread() {
// getdata and return as LiveData
}
public LiveData getWebViewDataInBackgroundThread(){
//获取数据并作为LiveData返回
}
阅读更多信息,使用上下文和活动生命周期相关人员在ViewModel
中专门查看ViewModel
将只保存数据并在数据和视图之间建立连接。在活动或片段中创建ProgressDialog
。使用>ViewModel
用于您的业务逻辑。在ViewModle
中为ProgressDialog
状态创建LiveData
。更改LiveData
值并在Activity
或Fragment
中观察它。这样您就可以决定何时显示ProgressDialog
或何时隐藏它。您的视图在Activity>中活动性
或片段
,不存在MemoryLeak的可能性
正如@tam huynh提到的,您的问题是您试图将应用程序上下文强制转换为无效的活动
在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 act = (Activity) webViewResult.getParent().getParent().....so on
如何更改此行:活动上下文=(活动)getApplication().getApplicationContext();to fragment.getActivity?如中所示,我不想将片段作为参数传递到该函数中。现在如何构造ViewModel
呢?发布其部分代码。此外,方法getApplication
来自何处?据我所知,getApplication
方法仅在Activity
编辑的问题中可用在…上