Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过引用viewmodel中的片段实现Android ClassCastException_Java_Android_Fragment_Viewmodel - Fatal编程技术网

Java 通过引用viewmodel中的片段实现Android ClassCastException

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

我在尝试引用viewmodel类中的片段时遇到了一些问题。下面是我的片段调用viewmodel的部分:

@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
编辑的问题中可用在…上