代码之家  ›  专栏  ›  技术社区  ›  QWERTY

Android ClassCastException,通过引用viewmodel中的片段

  •  0
  • QWERTY  · 技术社区  · 6 年前

    我在试图引用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);
    }
    
    4 回复  |  直到 6 年前
        1
  •  0
  •   Tam Huynh    6 年前

    Application Activity

    应用

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

    如果你在一个碎片里,只要简单地使用 fragment.getActivity()

        2
  •  0
  •   Udit    6 年前

    你得到了一个ClassCastException,因为你试图将应用程序强制转换为一个活动。

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

    决不应在ViewModel中使用对活动或片段的引用。永远不要从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
    }
    

    阅读更多 LiveData ViewModel

        3
  •  0
  •   Leonardo Roese    6 年前

    Activity act = (Activity) webViewResult.getParent().getParent().....so on
    
        4
  •  0
  •   Abu Yousuf    6 年前

    这不是一个好的做法 Context 而活动生命周期相关人员则专门查看里面 ViewModel . 将只保存数据并在数据和视图之间建立连接。创建 ProgressDialog 里面 Activity Fragment 视图模型 为了你的商业逻辑。创建 LiveData 对于 进度对话框 陈述 ViewModle . 改变 实时数据 活动 碎片 . 所以你可以决定什么时候表演 或者什么时候藏起来。你的视野在里面 活动 也不可能有记忆。

    活动 那是无效的。

    创建 视图模型

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

    活动 碎片

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

    Android Architecture Components