我开发了一个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
,是否有任何检查可以避免解雇?
答案 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);
}