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

How to avoid application crashing when launching AlertDialog using AsyncTask() in ANDROID?

在 Android 应用程序中,通过单击片段中的按钮,我想使用 AsynTask() 方法显示 AlertDialog。我在 onPreExecute() 中放置了调用 AlertDialog 的函数。在doInBackground(),有一个任务运行,在onPostExecute(),我驳回了AlertDialog。 就在我单击按钮时发生崩溃。并且引用了LoadingDialog中的行代码class,也就是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();
    }
    }

这是我的片段class


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)

您正在 AsyncTask 的 doInBackground() 中展示敬酒,这无法完成。 只能在主线程更新Ui

在后台线程 运行 中的 doInBackground() 中显示祝酒词 会引发异常,您的片段在那一刻被迫关闭,但是导致异常的对话框仍然打开。

所以尝试在 AsyncTask 的 onPostExecute 中调用 Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;

下面是 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);
        }
    }

除此之外,Vivek 还说:

  1. 将 ShowDialogAsyncTask 更改为静态 class
  2. 将对话框作为 WeakReference 传递,然后在它所在的每个地方使用 weakReference.get() 使用
  3. 显示对话框传递 context.getApplicationContext() 作为弱引用。

目前您的 Activity 正在通过 AsyncTask 泄漏。