4

我在应用程序上每隔一千多个会话就会收到一次此运行时异常,因此这种情况很少见,我无法重现它。

java.lang.IllegalArgumentException: View not attached to window manager
        at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:381)
        at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:226)
        at android.view.Window$LocalWindowManager.removeView(Window.java:432)
        at android.app.Dialog.dismissDialog(Dialog.java:278)
        at android.app.Dialog.access$000(Dialog.java:71)
        at android.app.Dialog$1.run(Dialog.java:111)
        at android.os.Handler.handleCallback(Handler.java:587)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:130)
        at android.app.ActivityThread.main(ActivityThread.java:3691)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:507)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670)
        at dalvik.system.NativeStart.main(Native Method)

有谁知道如何重现它,或者它为什么会发生?或者更好的是,如何解决它?:)

谢谢!

编辑:

我添加了 Raghav 提出的建议以添加以下内容:

<activity android:label="@string/app_name" 
        android:configChanges="orientation|keyboardHidden" 
        android:name="ActivityName">

但这并没有解决崩溃问题,并且崩溃仍在发生。

编辑:

这是我使用的一些典型代码:

public class ProblemActivity extends BaseListActivity
{
    Dialog dialog;

        ....


@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    ...

    // After some action
    dialog.show();
}

public class GetSolutionTopicsTask extends AsyncTask<String, Void, String> 
{
    @Override
    protected String doInBackground(String... theParams) 
    {
        String myUrl = theParams[0];
        String problem_id = theParams[1];

        String charset = "UTF-8";           
        String response = null;

        try 
        {               
            String query = String.format("problem_id=%s", 
                     URLEncoder.encode(problem_id, charset));

            final URL url = new URL( myUrl + "?" + query );

            final HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setDoOutput(true); 
            conn.setRequestMethod("POST");

            conn.setDoOutput(true);
            conn.setUseCaches(false);

            conn.connect();

            final InputStream is = conn.getInputStream();
            final byte[] buffer = new byte[8196];
            int readCount;
            final StringBuilder builder = new StringBuilder();
            while ((readCount = is.read(buffer)) > -1) 
            {
                builder.append(new String(buffer, 0, readCount));
            }

            response = builder.toString();      
        } 
        catch (Exception e) 
        {

        }

        return response;
    }

    @Override
    protected void onPostExecute(String result) 
    {           
        if ( result == null  )
        {
            try 
            {
                dialog.dismiss();
            } catch (Exception e) {
                // nothing
            }

        }
        else
        {
            try 
            {
                    dialog.dismiss();
                } 
            catch (Exception e) 
            {
                // nothing
                }    
         }  // End of else

}        
}        
4

7 回答 7

4

ConfigChanges 不会导致此问题。

从上面的日志看来,活动中显示的对话框在活动不再可见后被关闭。

如果您共享了代码或至少给出了导致崩溃的步骤,我可以建议修复。

于 2012-11-07T06:18:59.130 回答
3

在某些设备和某些情况下,活动在对话框成功关闭或异步任务在后台运行之前完成,因此当您调用对话框关闭它会导致

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

因为主 ui 线程已被解除。

为了解决这个问题,您可以跟踪活动是否完成,因此在活动的 onStop 中使对话框为空,然后在 onPostExecute 检查对话框的状态;代码会像

@Override
public void onStop() {
    super.onStop();
    dialog = null;
}

并在 onpostexecute

if (dialog != null) { 
        dialog.dismiss();
   }
于 2012-11-09T10:09:12.500 回答
2

当您切换方向时,Android 将创建一个新视图。您可能会崩溃,因为您的后台线程正在尝试更改旧线程的状态。(它也可能有问题,因为您的后台线程不在 UI 线程上)

在您的特定情况下,您似乎正试图在对话框发生时关闭它,可能来自 AsyncTask 或后台线程。

要修复它,请尝试以下操作:

<activity android:label="@string/app_name" 
        android:configChanges="orientation|keyboardHidden" 
        android:name="ActivityName">

问题是当配置发生变化时系统会破坏活动。请参阅配置更改

所以把它放在配置文件中可以避免系统破坏你的活动。相反,它调用 onConfigurationChanged(Configuration) 方法。

这里还有一个类似的更老的问题有更多的解决方案。我目前的答案是那里的两个答案的混合。

于 2012-10-27T19:14:13.587 回答
2

您是否使用AsyncTask可以在活动被破坏后完成的?未附加到窗口管理器的 android View有一些答案。

此外,如果您的应用程序以 API 13 或更高版本为目标,您应该在清单中使用它而不是 Raghav 的建议(屏幕尺寸随着新 API 中的方向而变化):

    <activity android:label="@string/app_name" 
    android:configChanges="orientation|keyboardHidden|screenSize" 
    android:name="ActivityName">
于 2012-11-07T01:23:13.703 回答
2
private class LongOperation extends AsyncTask<String, Void, String> {

  @Override
  protected String doInBackground(String... params) {
     String response = "";

     for(int i=0;i<5;i++) {
         try {
             response =i;
             Thread.sleep(1000);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
     }

     return response;
  }      

  @Override
  protected void onPostExecute(String result) { 
     TextView txt = (TextView) findViewById(R.id.output);
     txt.setText(result); 
  }

  @Override
  protected void onPreExecute() {

  }

  @Override
  protected void onProgressUpdate(Void... values) {

  }

}

用你的代码改变它。是版本问题。在第三版之后,我们不在主线程中设置视图,所以我们必须使用异步任务......

于 2012-11-07T06:11:50.440 回答
2

在活动的 onStop 中关闭对话框。另外在调用解除检查之前

dialog.isShowing()是真是假。

if(dialog.isShowing())dialog.dismiss();

从源代码

private int  findViewLocked(View view, boolean required){       
    synchronized (this){        
        final int count = mViews != null ? mViews.length : 0;
        for (int i=0; i<count; i++) {               
            if (mViews[i] == view) { 
                return i;               
            }
        }           
        if (required) {             
            throw new IllegalArgumentException( "View not attached to window manager");         
        } 
        return -1;      
    }   
}

由于您收到此异常,这意味着调用关闭时未找到该视图。

于 2012-11-08T06:22:15.200 回答
2

正如 Chinmoy Debnath 指出的那样,我很确定是 Dialog 导致了这个问题。

于 2012-11-11T08:49:16.227 回答