如何在使用ANDROID中的AsyncTask()启动AlertDialog时避免应用程序崩溃?

问题描述 投票:2回答:2

在Android应用程序中,通过单击片段中的按钮,我想使用AsynTask()方法显示AlertDialog。我在onPreExecute()中放置了一个称为AlertDialog的函数。在doInBackground()中有一个正在运行的任务,在onPostExecute()中我关闭了AlertDialog。仅在单击按钮时发生崩溃。并且它引用LoadingDialog类中的行代码,即dialog.show();。我已经尝试过在网站上给出的许多建议,但是问题再次出现。有人可以帮我吗?

这是LoadingDialog.java


    public class LoadingDialog {

    private Activity activity;
    private AlertDialog dialog;

    LoadingDialog(Activity myActivity){
        activity = myActivity;
    }

    public void startLoadingDialog(){
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);

        LayoutInflater inflater = activity.getLayoutInflater();
        builder.setView(inflater.inflate(R.layout.custom_dialog, null));
        builder.setCancelable(false);

        dialog = builder.create();
        dialog.show();
    }

    public void dismissDialog(){
        dialog.dismiss();
    }
    }

这是我的Fragment类


public class MyFragment extends Fragment {

    View view ;
    private Button btn_;
    private Activity activity;
    private AlertDialog dialog;
    private LoadingDialog loadingDialog;

    public MyFragment(){

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        this.view = inflater.inflate(R.layout.fragment_, container, false);

        loadingDialog = new LoadingDialog(getActivity());

        btn_ = this.view.findViewById(R.id._button);
        eventListnerReinitialiser();
        return this.view;
    }

    public void eventListnerReinitialiser() {
        this.btn_.setOnClickListener(v -> {
             new ShowDialogAsyncTask().execute();
        });
    }

    public class ShowDialogAsyncTask extends AsyncTask<Void, Void, Void> {
        int s = 0;
        @Override
        protected void onPreExecute() {
            loadingDialog.startLoadingDialog();
            super.onPreExecute();
        }
        @Override
        protected Void doInBackground(Void... params) {
            for(int i=0;i<1000000;i++)
                s = s + i;
            Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            loadingDialog.dismissDialog();
            super.onPostExecute(result);
        }
    }

}

并且我在Android Studio的控制台中有此错误日志


    E/WindowManager: android.view.WindowLeaked: Activity com.example.myproject.Menu2Activity has leaked window DecorView@96c506[] that was originally added here
        at android.view.ViewRootImpl.<init>(ViewRootImpl.java:511)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:338)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
        at android.app.Dialog.show(Dialog.java:322)
android android-asynctask android-alertdialog
2个回答
0
投票
您只能在主线程中更新Ui。

在[[在后台线程中运行]的doInBackground()中显示吐司]会引发异常,并且此时您的片段被迫关闭,但对话框仍处于打开状态,从而导致了异常。因此,尝试在AsyncTask的Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;中调用onPostExecute

这里是如何执行AsyncTask部分。

public class ShowDialogAsyncTask extends AsyncTask<Void, Void, Void> { int s = 0; @Override protected void onPreExecute() { loadingDialog.startLoadingDialog(); super.onPreExecute(); } @Override protected Void doInBackground(Void... params) { for(int i=0;i<100_000_000;i++) s = s + i; return null; } @Override protected void onPostExecute(Void result) { Toast.makeText(MainActivity.this, "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ; loadingDialog.dismissDialog(); super.onPostExecute(result); } }

0
投票
将ShowDialogAsyncTask更改为静态类

以WeakReference的形式传递对话框,然后在每个位置使用weakReference.get()使用

    要显示对话框,请将context.getApplicationContext()作为弱引用。
  1. 当前您的活动正在通过AsyncTask泄漏。
© www.soinside.com 2019 - 2024. All rights reserved.