E/AndroidRuntime(9916): java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{43805410 V.E..... R.....ID 0,0-1026,288} not attached to window manager
E/AndroidRuntime(9916): at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:370)E/AndroidRuntime(9916): at android.app.Dialog.dismiss(Dialog.java:312)
在将progressDialog 用在ASyncTask中的时候,有时候会遇到上面的错误。
我们先看一下,最常用的AsyncTask中使用ProgressDialog的方法。下面是最常用的使用方法。
public class HttpRequestTask extends AsyncTask <String, Void, String> { Context ctx = null; private ProgressDialog dialog = null; public interface HttpRequestTaskListener { void ServerResponse (String jsonStr); } public HttpRequestTask (final Context c){ ctx = c; dialog = new ProgressDialog(c); } public void addListener (HttpRequestTaskListener l){ listeners.add(0, l); } protected void onPreExecute() { dialog.setMessage("Downloading data from the Server..."); dialog.show(); } @Override protected String doInBackground(String... params) { String url = params[0]; return HttpRequest ( url, .......); } @Override protected void onPostExecute(String result) { if (dialog.isShowing()) { dialog.dismiss(); } if (listeners.size() > 0){ listeners.get(0).ServerResponse ( result ); } } }
一般情况下,上面的方法不会出现任何错误。 任务结束后,ProgressDialog会正常消失。
但是在某些情况下,上面的使用方法就非常不安全。
在项目开发中会遇到在TabView的各个tab page进行切换。同时每个tab page中都会调用
这个异步任务HttpRequestTask去请求网络数据。这时会出现一个问题。
当用户在各个tab page间快速切换的时候,ProgressDialog 使用的context就很不安全。
会遇到调用 dialog.dismiss 和 dialog.show(); 的时候无法attach到Window Manager.
原因是在切换的时候,dialog还没有完成所有的调用,所对应的context已经被destroy或正在destroy。
这时就会导致上面的错误。
尝试解决这个问题。最初想使用ApplicationContext,(context.getApplicationContext()),但是,这个context无法用于ProgressDialog和Toast。会直接导致crash。
目前的解决方法是,先检查context对应的Activity的状态,如果不可用就停止dialog操作:
public class HttpRequestTask extends AsyncTask <String, Void, String> { Context ctx = null; private ProgressDialog dialog = null; public interface HttpRequestTaskListener { void ServerResponse (String jsonStr); } public HttpRequestTask (final Context c){ ctx = c; dialog = new ProgressDialog(c); } public void addListener (HttpRequestTaskListener l){ listeners.add(0, l); } protected void onPreExecute() { if (isValidContext(ctx)){ dialog.setMessage("Downloading data from the Server..."); dialog.show(); } } @Override protected String doInBackground(String... params) { String url = params[0]; return HttpRequest ( url, .......); } @Override protected void onPostExecute(String result) { if (isValidContext(ctx) && dialog.isShowing()) { dialog.dismiss(); } if (listeners.size() > 0){ listeners.get(0).ServerResponse ( result ); } } } private boolean isValidContext (Context c){ Activity a = (Activity)c; if (a.isDestroyed() || a.isFinishing()){ Log.i("YXH", "Activity is invalid." + " isDestoryed-->" + a.isDestroyed() + " isFinishing-->" + a.isFinishing()); return false; }else{ return true; } }