Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 视图未连接到窗口管理器崩溃_Android - Fatal编程技术网

Android 视图未连接到窗口管理器崩溃

Android 视图未连接到窗口管理器崩溃,android,Android,我正在使用ACRA报告应用程序崩溃。我收到一条未附加到窗口管理器的视图错误消息,并认为我已通过包装pDialog.disclose()修复了它在if语句中: if (pDialog!=null) { if (pDialog.isShowing()) { pDialog.dismiss(); } } 它减少了未连接到窗口管理器的视图崩溃的数量,但我仍然收到一些,我不知道如何解决它 错误消息: java.lang.IllegalArgumentEx

我正在使用ACRA报告应用程序崩溃。我收到一条未附加到窗口管理器的
视图
错误消息,并认为我已通过包装
pDialog.disclose()修复了它在if语句中:

if (pDialog!=null) 
{
    if (pDialog.isShowing()) 
    {
        pDialog.dismiss();   
    }
}
它减少了未连接到窗口管理器的
视图
崩溃的数量,但我仍然收到一些,我不知道如何解决它

错误消息:

java.lang.IllegalArgumentException: View not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:425)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:327)
at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:83)
at android.app.Dialog.dismissDialog(Dialog.java:330)
at android.app.Dialog.dismiss(Dialog.java:312)
at com.package.class$LoadAllProducts.onPostExecute(class.java:624)
at com.package.class$LoadAllProducts.onPostExecute(class.java:1)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
代码段:

class LoadAllProducts extends AsyncTask<String, String, String> 
{

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() 
    {
        super.onPreExecute();
        pDialog = new ProgressDialog(CLASS.this);
        pDialog.setMessage("Loading. Please wait...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    /**
     * getting All products from url
     * */
    protected String doInBackground(String... args) 
    {
        // Building Parameters
        doMoreStuff("internet");
        return null;
    }


    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) 
    {
         // dismiss the dialog after getting all products
         if (pDialog!=null) 
         {
                if (pDialog.isShowing()) 
                {
                    pDialog.dismiss();   //This is line 624!    
                }
         }
         something(note);
    }
}
class LoadAllProducts扩展异步任务
{
/**
*在启动后台线程显示进度对话框之前
* */
@凌驾
受保护的void onPreExecute()
{
super.onPreExecute();
pDialog=新建进度对话框(CLASS.this);
pDialog.setMessage(“正在加载,请稍候…”);
pDialog.setUndeterminate(假);
pDialog.setCancelable(假);
pDialog.show();
}
/**
*从url获取所有产品
* */
受保护的字符串doInBackground(字符串…args)
{
//建筑参数
多莫斯图夫(“互联网”);
返回null;
}
/**
*完成后台任务后,关闭“进度”对话框
* **/
受保护的void onPostExecute(字符串文件\u url)
{
//获取所有产品后关闭对话框
如果(pDialog!=null)
{
if(pDialog.isShowing())
{
pDialog.disclose();//这是第624行!
}
}
某物(注);
}
}
舱单:

    <activity
        android:name="pagename.CLASS" 
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"            
        android:label="@string/name" >
    </activity>


我缺少什么来阻止崩溃的发生?

如何重现错误:

  • 在设备上启用此选项:
    设置->开发人员选项->不保留活动
  • 在执行
    AsyncTask
    并显示
    ProgressDialog
    时,按Home按钮
  • 一旦某个活动被隐藏,Android操作系统将立即销毁该活动。调用
    onPostExecute
    时,
    活动将处于“完成”状态,
    ProgressDialog
    将不会附加到
    活动

    如何修复它:

  • 检查
    onPostExecute
    方法中的活动状态
  • 关闭
    ondestory
    方法中的
    ProgressDialog
    。否则,将引发异常。此异常通常来自活动完成时仍处于活动状态的对话框
  • 请尝试以下固定代码:

    public class YourActivity extends Activity {
    
        private void showProgressDialog() {
            if (pDialog == null) {
                pDialog = new ProgressDialog(StartActivity.this);
                pDialog.setMessage("Loading. Please wait...");
                pDialog.setIndeterminate(false);
                pDialog.setCancelable(false);
            }
            pDialog.show();
        }
    
        private void dismissProgressDialog() {
            if (pDialog != null && pDialog.isShowing()) {
                pDialog.dismiss();
            }
        }
    
        @Override
        protected void onDestroy() {
            dismissProgressDialog();
            super.onDestroy();
        }
    
        class LoadAllProducts extends AsyncTask<String, String, String> {
    
            // Before starting background thread Show Progress Dialog
            @Override
            protected void onPreExecute() {
                showProgressDialog();
            }
    
            //getting All products from url
            protected String doInBackground(String... args) {
                doMoreStuff("internet");
                return null;
            }
    
            // After completing background task Dismiss the progress dialog
            protected void onPostExecute(String file_url) {
                if (YourActivity.this.isDestroyed()) { // or call isFinishing() if min sdk version < 17
                    return;
                }
                dismissProgressDialog();
                something(note);
            }
        }
    }
    
    公共类YourActivity扩展活动{
    私有void showProgressDialog(){
    如果(pDialog==null){
    pDialog=新建进度对话框(StartActivity.this);
    pDialog.setMessage(“正在加载,请稍候…”);
    pDialog.setUndeterminate(假);
    pDialog.setCancelable(假);
    }
    pDialog.show();
    }
    私有void dismissProgressDialog(){
    if(pDialog!=null&&pDialog.isShowing()){
    pDialog.disclose();
    }
    }
    @凌驾
    受保护的空onDestroy(){
    dismissProgressDialog();
    super.ondestory();
    }
    类LoadAllProducts扩展了AsyncTask{
    //在启动后台线程显示进度对话框之前
    @凌驾
    受保护的void onPreExecute(){
    showProgressDialog();
    }
    //从url获取所有产品
    受保护的字符串doInBackground(字符串…args){
    多莫斯图夫(“互联网”);
    返回null;
    }
    //完成后台任务后,关闭“进度”对话框
    受保护的void onPostExecute(字符串文件\u url){
    如果(YourActivity.this.isDestroyed()){//或者如果min sdk版本<17,则调用isFinishing()
    返回;
    }
    dismissProgressDialog();
    某物(注);
    }
    }
    }
    
    覆盖OnConfiguration更改并关闭进度对话框。 若进度对话框是在纵向创建的,在横向中关闭,那个么它将抛出“视图未附加到窗口管理器”错误

    另外,在onPause()、onBackPressed和onDestroy方法中停止进度条并停止异步任务

    if(asyncTaskObj !=null && asyncTaskObj.getStatus().equals(AsyncTask.Status.RUNNING)){
    
        asyncTaskObj.cancel(true);
    
    }
    

    在此处查看代码的工作方式:

    调用异步任务后,异步任务在后台运行。这是可取的。现在,如果您询问如何查看代码,此异步任务有一个附加到活动的进度对话框:

    pDialog = new ProgressDialog(CLASS.this);
    
    您正在将
    类作为上下文传递给参数。因此,“进度”对话框仍然附加到活动

    现在考虑一下情况: 如果我们尝试在异步任务正在进行时使用finish()方法完成活动,则当活动已不存在时,您正试图访问附加到活动的资源(即
    进度条

    因此你得到:

    java.lang.IllegalArgumentException: View not attached to the window manager
    
    解决方案:

    1) 确保在“活动”完成之前关闭或取消对话框


    2) 只有在对话框关闭后,即异步任务结束后,才能完成活动。

    问题可能是
    活动
    完成
    或正在
    完成

    添加一个检查
    isFinishing
    ,仅当该检查为
    false

    if (!YourActivity.this.isFinishing() && pDialog != null) {
        pDialog.dismiss();
    }
    
    isFinishing:检查此活动是否正在完成,原因可能是您调用了它的
    finish
    ,或者其他人请求它完成


    参考

    此问题是因为您的活动在调用dismise函数之前完成。处理异常并检查ADB日志以了解确切原因

    /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {
        try {
             if (pDialog!=null) {
                pDialog.dismiss();   //This is line 624!    
             }
        } catch (Exception e) {
            // do nothing
        }
         something(note);
    }
    

    基于@erakitin answer,但也兼容API级别17以下的Android版本。不幸的是,它只在API级别17之后才被支持,所以如果你像我一样瞄准一个较旧的API级别,你将不得不
    /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {
        try {
             if (pDialog!=null) {
                pDialog.dismiss();   //This is line 624!    
             }
        } catch (Exception e) {
            // do nothing
        }
         something(note);
    }
    
    public class MainActivity extends Activity {
        private TestAsyncTask mAsyncTask;
        private ProgressDialog mProgressDialog;
        private boolean mIsDestroyed;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (condition) {
                mAsyncTask = new TestAsyncTask();
                mAsyncTask.execute();
            }
        }
    
        @Override
        protected void onResume() {
            super.onResume();
    
            if (mAsyncTask != null && mAsyncTask.getStatus() != AsyncTask.Status.FINISHED) {
                Toast.makeText(this, "Still loading", Toast.LENGTH_LONG).show();
                return;
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            mIsDestroyed = true;
    
            if (mProgressDialog != null && mProgressDialog.isShowing()) {
                mProgressDialog.dismiss();
            }
        }
    
        public class TestAsyncTask extends AsyncTask<Void, Void, AsyncResult> {    
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                mProgressDialog = ProgressDialog.show(MainActivity.this, "Please wait", "doing stuff..");
            }
    
            @Override
            protected AsyncResult doInBackground(Void... arg0) {
                // Do long running background stuff
                return null;
            }
    
            @Override
            protected void onPostExecute(AsyncResult result) {
                // Use MainActivity.this.isDestroyed() when targeting API level 17 or higher
                if (mIsDestroyed)// Activity not there anymore
                    return;
    
                mProgressDialog.dismiss();
                // Handle rest onPostExecute
            }
        }
    }
    
    protected void onDestroy ()
        {
            if(mProgressDialog != null)
                if(mProgressDialog.isShowing())
                    mProgressDialog.dismiss();
            mProgressDialog= null;
        }
    
    public class MainActivity extends Activity {
        private static final String TAG = "MainActivity";
        private ProgressDialog mProgressDialog;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Log.d(TAG, "onCreate");
    
            new AsyncTask<Void, Void, Void>(){
                @Override
                protected void onPreExecute() {
                    mProgressDialog = ProgressDialog.show(MainActivity.this, "", "plz wait...", true);
                }
    
                @Override
                protected Void doInBackground(Void... nothing) {
                    try {
                        Log.d(TAG, "long thread doInBackground");
                        Thread.sleep(20000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                    return null;
                }
    
                @Override
                protected void onPostExecute(Void result) {
                    Log.d(TAG, "long thread onPostExecute");
                    if (mProgressDialog != null && mProgressDialog.isShowing()) {
                        mProgressDialog.dismiss();
                        mProgressDialog = null;
                    }
                    Log.d(TAG, "long thread onPostExecute call dismiss");
                }
            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    
            new AsyncTask<Void, Void, Void>(){
                @Override
                protected Void doInBackground(Void... params) {
                    try {
                        Log.d(TAG, "short thread doInBackground");
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return null;
                }
    
                @Override
                protected void onPostExecute(Void aVoid) {
                    super.onPostExecute(aVoid);
                    Log.d(TAG, "short thread onPostExecute");
                    finish();
                    Log.d(TAG, "short thread onPostExecute call finish");
                }
            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            Log.d(TAG, "onDestroy");
        }
    }
    
    if (context instanceof Activity) {
       if (!((Activity) context).isFinishing())
         dialog.show();
    }
    
    if (context instanceof Activity) {
           if (!((Activity) context).isFinishing())
             dialog.dismiss();
        }
    
    ProgressDialog myDialog = new ProgressDialog(getActivity());
    myDialog.setOwnerActivity(getActivity());
    ...
    Activity activity = myDialog.getOwnerActivity();
    if( activity!=null && !activity.isFinishing()) {
        myDialog.dismiss();
    }
    
    private int findViewLocked(View view, boolean required) {
            final int index = mViews.indexOf(view);
    //here, view is decorView,comment by OF
            if (required && index < 0) {
                throw new IllegalArgumentException("View=" + view + " not attached to window manager");
            }
            return index;
        }
    
    try {
                Class<?> windowMgrGloable = Class.forName("android.view.WindowManagerGlobal");
                try {
                    Method mtdGetIntance = windowMgrGloable.getDeclaredMethod("getInstance");
                    mtdGetIntance.setAccessible(true);
                    try {
                        Object windownGlobal = mtdGetIntance.invoke(null,null);
                        try {
                            Field mViewField = windowMgrGloable.getDeclaredField("mViews");
                            mViewField.setAccessible(true);
                            ArrayList<View> mViews = (ArrayList<View>) mViewField.get(windownGlobal);
                            int decorViewIndex = mViews.indexOf(pd.getWindow().getDecorView());
                            Log.i(TAG,"check index:"+decorViewIndex);
                            if (decorViewIndex < 0) {
                                return;
                            }
                        } catch (NoSuchFieldException e) {
                            e.printStackTrace();
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            if (pd.isShowing()) {
                pd.dismiss();
            }
    
    @Override
    protected void onPause() {
        super.onPause();
        dialog.dismiss();
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        dialog.dismiss();
    }
    
    @Override
    public void dismiss() {
        Window window = getWindow();
        if (window == null) {
            return;
        }
        View decor = window.getDecorView();
        if (decor != null && decor.getParent() != null) {
            super.dismiss();
        }
    }
    
    if (pDialog instanceof Activity && !((Activity) mContext).isFinishing())
            pDialog.show();