解雇AsyncTask中的ProgressDialog时出现非常异常的错误

时间:2012-08-28 14:21:28

标签: android android-asynctask progressdialog

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

java.lang.IllegalArgumentException: View not attached to window manager

当我解雇ProgressDialog时会发生此错误。此dialog位于AsyncTask。这是我的代码:

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

}

如何以编程方式避免此错误?如果不是attached to window manager,是否有任何检查可以避免解雇?

4 个答案:

答案 0 :(得分:4)

你在OnCreate中实例化LoadGatesAsyncTask吗?

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

答案 1 :(得分:2)

您可以添加支票:

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

答案 2 :(得分:2)

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

如果初始化对象 - AsynTask,则会调用构造函数。因此,您的ProgressDialog会被显示,但您还没有在AsyncTask上调用.execute()!因此,当您试图解雇它时,编译器会发现自己处于不同的线程。

编辑:澄清误解的陈述。

答案 3 :(得分:1)

我认为真正的问题是Activity背后的progressDialog背后的真实问题,

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

这样progressDialog.OwnerActivity= null (通常在调用onCreate时)

它是通过将新重新创建的Activity附加到所有者来解决的:progressDialog.OwnerActivity = myActivity;(它将在您的类中传递一个本地参数,在构造函数中传递它, 喜欢:(这里是C#android,类似于java ..同样的想法)

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