-1

我开发了一个 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

4 回答 4

4

你在 OnCreate 中实例化 LoadGatesAsyncTask 吗?

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

于 2012-08-28T14:30:18.787 回答
2

您可以添加支票:

if(mLoadingDialog.isShowing()){
   mLoadingDialog.dismiss();
}
于 2012-08-28T14:31:00.830 回答
2

ProgressDialog在构造函数中初始化 this ,而不是 in onPreExecute(),这是错误的,因为您正在关闭ProgressDialogin onPostExecute,您需要在同一个UI 线程上执行此操作。

如果你初始化对象 - AsynTask,你会调用你的构造函数。所以你的ProgressDialog将被显示,但你还没有调用.execute()AsyncTask!因此,当您尝试关闭它时,编译器会发现自己位于不同的线程上。

编辑:澄清被误解的陈述。

于 2012-08-28T14:31:39.763 回答
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);
}
于 2013-10-26T20:14:02.740 回答