Android 在AsyncTask中关闭ProgressDialog时出现非常异常的错误

Android 在AsyncTask中关闭ProgressDialog时出现非常异常的错误,android,android-asynctask,progressdialog,Android,Android Asynctask,Progressdialog,我开发了一个Android 2.2应用程序,我只收到一次此错误: java.lang.IllegalArgumentException: View not attached to window manager 当我关闭ProgressDialog时,会发生此错误。此对话框位于异步任务上。这是我的密码: private class LoadGatesAsyncTask extends AsyncTask<Void, Void, Boolean> { private Conte

我开发了一个Android 2.2应用程序,我只收到一次此错误:

java.lang.IllegalArgumentException: View not attached to window manager
当我关闭
ProgressDialog
时,会发生此错误。此
对话框
位于
异步任务
上。这是我的密码:

private class LoadGatesAsyncTask extends AsyncTask<Void, Void, Boolean>
{
    private Context mContext;
    private ArrayList<Gate> mGatesList;
    private ProgressDialog mLoadingDialog;

    public LoadGatesAsyncTask(Context context)
    {
        this.mContext = context;
        mLoadingDialog = new ProgressDialog(mContext);
        mLoadingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mLoadingDialog.setMessage(getString(R.string.msg_loading_gates));
        mLoadingDialog.setCancelable(false);
        mLoadingDialog.show();
    }

    @SuppressWarnings("unchecked")
    @Override
    protected Boolean doInBackground(Void... params)
    {
        Boolean result = false;

        try
        {
            [ ... ]
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return result;
    }

    @Override
    protected void onPostExecute(Boolean result)
    {
        super.onPostExecute(result);

        if (result)
        {
            [ ... ]

            mLoadingDialog.dismiss();
        }
        else
        {
            mLoadingDialog.dismiss();
            Toast toast = Toast.makeText(mContext,
                    getString(R.string.msg_error_loading_gates),
                    Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.CENTER, 
                    toast.getXOffset() / 2,
                    toast.getYOffset() / 2);

            toast.show();
        }
    }

}
私有类LoadGatesAsyncTask扩展异步任务
{
私有上下文;
私人阵列列表管理列表;
私有进程对话框mLoadingDialog;
公共加载网关同步任务(上下文)
{
this.mContext=上下文;
mLoadingDialog=新建进度对话框(mContext);
mLoadingDialog.setProgressStyle(ProgressDialog.STYLE_微调器);
setMessage(getString(R.string.msg_加载门));
mLoadingDialog.setCancelable(false);
mLoadingDialog.show();
}
@抑制警告(“未选中”)
@凌驾
受保护的布尔doInBackground(Void…params)
{
布尔结果=假;
尝试
{
[ ... ]
}
捕获(例外情况除外)
{
例如printStackTrace();
}
返回结果;
}
@凌驾
受保护的void onPostExecute(布尔结果)
{
super.onPostExecute(结果);
如果(结果)
{
[ ... ]
mLoadingDialog.disclose();
}
其他的
{
mLoadingDialog.disclose();
Toast Toast=Toast.makeText(mContext,
getString(R.string.msg\u错误\u加载\u门),
烤面包片(长/短);
toast.setGravity(重心,
toast.getXOffset()/2,
toast.getYOffset()/2);
toast.show();
}
}
}

如何以编程方式避免此错误?如果它没有连接到窗口管理器,我是否可以做一些检查来避免将其关闭?

是否在OnCreate中实例化LoadGateSsyncTask


如果是这样,请将loadingDialog实例化移动到
OnPreExecute
而不是构造函数中。

您可以添加检查:

if(mLoadingDialog.isShowing()){
   mLoadingDialog.dismiss();
}

您正在构造函数中初始化此
ProgressDialog
,而不是在
onPreExecute()
中,这是错误的,因为您在
onPostExecute
中取消了
ProgressDialog
,您需要在相同的UI线程上执行此操作

如果初始化对象AsynTask,将调用构造函数。因此,将显示您的
ProgressDialog
,但您尚未对AsyncTask调用
.execute()
!因此,当您试图取消它时,编译器发现自己位于不同的线程上


编辑:澄清误解。

我认为真正的问题在于所附
活动的背后
进度对话框的背后

它正在更改为新的引用(实例)

因此,
progressDialog.OwnerActivity=
null(通常在调用onCreate时进行轮换)

可以通过将新创建的活动附加到所有者来解决此问题:
progressDialog.OwnerActivity=myActivity(将在类中传递一个本地参数,在构造函数中传递它,
比如:(这里是C#android,类似于java,想法相同)


你试过了吗
或类似的解除之前?可能重复“否”,它在onResume上实例化。您只能在显示所有活动后附加一个窗口。这仅在onResume之后发生。因此,您只能在onResume完成执行后显示对话框确保构造函数不会与调用方在同一线程中运行?如果o我猜onCreate()在UI线程中像onPreExecute()一样运行是的。错?!如果我从UI线程构造AsyncTask对象,不要告诉我对象创建也不会在UI线程上!根据中的
线程规则
,你错了:
任务实例必须在UI线程上创建
对不起。
你需要在GUI线程aka上进行,而不是在构造函数中e> 很难误解。你是说构造函数不在GUI线程上。这完全是错误的!你的完整答案只是关于GUI线程和构造函数…我没有回答这个问题。无论如何,你应该更仔细地阅读文档。execute()也必须在UI线程上调用。稍后调用某些内容并不意味着它是从另一个线程调用的。答案中的最后一句也是错误的。只有一个UI线程。从同一个线程调用构造函数execute()、onPreExecute()和onPostExecute(),始终是UI线程!execute()在内部创建一个新线程并在此线程中运行doInBackground()。我不确定您对线程的熟悉程度,但您应该阅读有关AsyncTask的更多信息。
class ProgressDialogAsync: AsyncTask //extends asynctask
{
//used parameters

Activity Activity;

string Title;
string Message;

ProgressDialog AsyncDialog;

public ProgressDialogAsync(Activity Activity, string Title, string Message)
 {    
  this.Title = Title;
  this.Message = Message;
  this.Activity = Activity;
 }


protected override void OnPreExecute()
{
 AsyncDialog = new ProgressDialog(Activity);
}

protected override Java.Lang.Object DoInBackground(params Java.Lang.Object[] @params)       {
 //do background operation
}

protected override void OnPostExecute(Java.Lang.Object result)
{
 //do something
 AsyncDialog.OwnerActivity = Activity;
 AsyncDialog.Dismiss();
 base.OnPostExecute(result);
}