4

I am getting this runtime exception about once every thousand+ sessions on the app, so it is rare and I have not been able to reproduce it.

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)

Would anyone know how to reproduce it, or why it happens? Or better yet, how to fix it? :)

Thanks!

EDIT:

I added the suggestion made by Raghav to add this:

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

But this has not fixed the crashing and the crashing is still happening.

EDIT:

Here is some typical code I use:

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

}        
}        
Genadinik
  • 18,153
  • 63
  • 185
  • 284
  • Can you show some code where its happening? – wtsang02 Oct 27 '12 at 19:08
  • @wtsang02 actually this is part of the problem - there is no reference in this exception to any of my classes :) I don't know which code is causing it. – Genadinik Oct 27 '12 at 19:13
  • 1
    That's the kind of stack I hate : when your own code is not showing in the trace, but the user sees "the application blah blah..." anyway. :/ Difficult to track and solve... – Orabîg Oct 27 '12 at 19:14
  • I meant which activity, does it happen in the same part of the app? and View not attached to window manager,possibly caused by: a popup created by thread, or orientation changes. – wtsang02 Oct 27 '12 at 19:16
  • Similar: http://stackoverflow.com/questions/2745061/java-lang-illegalargumentexception-view-not-attached-to-window-manager – pawelzieba Nov 06 '12 at 09:17
  • Are you sure the device generating the exception has updated to the latest version? – Raghav Sood Nov 06 '12 at 18:10
  • The only way I've found to trackdown exceptions in "external libraries" is the good-ole deskcheck method... first you need to acquire a copy of `WindowManagerImpl.java` starting at line 381 thereof, and traceback to locate where/why the `[The] view [is] not attached to [the] window manager`. If you can't get the source-code for your android platform then I guess you'll need to decompile it. – corlettk Nov 07 '12 at 06:23
  • It would be a good idea for debugging to put any code that may throw an exception in a try-catch block and add some Log.e output to give yourself some more useful info. – esse Nov 10 '12 at 00:41
  • 1
    First of all, could you also edit your question and put there exactly when this error comes. i mean, yeah it comes once in a thousand session but still, when it comes, what had happend? secondly, just a rough guess, may be in that particular session, dialog isn't created and when in asynctask you dismiss it, it gave you exception that dialog isn't attached so cant remove.. something like that... you can probably check before dismissing, whether dialog is attached or created or some function like this... – Farhan Nov 12 '12 at 10:00

7 Answers7

4

ConfigChanges are not causing this issue.

From the above logs it seems, that a dialog which was displayed in the activity was being dismissed after the activity is no longer visible.

If you shared the code or atleast give the steps you perform to get the crash, I can suggest a fix.

Abhishek Nandi
  • 4,265
  • 1
  • 30
  • 43
  • It's not that easy mate. The crux of the question is *HOW TO work-out "the steps you perform to get the crash"...* and because the error is in a "sealed framework" that can only be done (AFAIK) by surmise based on an understanding of how the framework works, at the source level. – corlettk Nov 07 '12 at 06:27
  • from the logs its clear that `Handler` dispatched a message to dismiss the dialog, which calls a runnable `mDismissAction` [`Dialog$1`] that calls `dissmissDialog()`. I looked at the source code of `Dialog` class and it perfectly made sense. – Abhishek Nandi Nov 07 '12 at 07:58
3

In some devices and also some cases activity gets finished before dialog successfully dismisses or asynchronous task is running in background , so when you call the dialoge to dismiss it causes

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

as the main ui thread is already dismissed.

In order to solve this you can track if the activity finished , so make the dialog null in onStop of the activity and then in onPostExecute check the status of the dialog; Code will be like

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

and in onpostexecute

if (dialog != null) { 
        dialog.dismiss();
   }
Chinmoy Debnath
  • 2,814
  • 16
  • 20
2

When you switch orientations, Android will create a new View. You're probably getting crashes because your background thread is trying to change the state on the old one. (It may also be having trouble because your background thread isn't on the UI thread)

In your specific case, it seems you are trying to dismiss a dialog when it happens, probably from an AsyncTask or a background Thread.

To fix it, try the following:

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

The matter is that the system destroys the activity when a change in the configuration occurs. See ConfigurationChanges.

So putting that in the configuration file avoids the system to destroy your activity. Instead it invokes the onConfigurationChanged(Configuration) method.

There is also a similar and older question here, with more solutions. My current answer is a mix of two answers from there.

Community
  • 1
  • 1
Raghav Sood
  • 81,899
  • 22
  • 187
  • 195
  • Well, I can tell you it wasn't me :P But the answer may not be correct 100% to your situation. However, it should provide you with a starting point, and the fix should work, regardless of whether or not your problem is the exact same as the person in the other question. – Raghav Sood Oct 27 '12 at 19:27
  • I upvoted you back. I will implement this, put it live, and see if I get anymore crashes. If not, I will accept the answer. Thank you. – Genadinik Oct 27 '12 at 19:33
  • By the way, does it matter which order is android:configChanges="orientation|keyboardHidden" in? Would this be the same: android:configChanges="keyboardHidden|orientation" ? – Genadinik Oct 27 '12 at 19:34
  • I didn't -1, but I'm guessing it is because too little info is given to even answer this question. – wtsang02 Oct 27 '12 at 19:42
  • 1
    If the OP doesn't have any information himself, as the stack trace points to code outside of his app, then you have to answer based on guesses. A slightly wrong answer is more helpful than no answer. Plus, there aren't too many ways to get this exception. – Raghav Sood Oct 27 '12 at 19:44
  • +1 for *A slightly wrong answer is more helpful than no answer.* – corlettk Nov 07 '12 at 06:30
2

Do you use an AsyncTask that could finish after the activity is destroyed? android View not attached to window manager has some answers.

Also, if your application targets API 13 or higher, you should use this in your manifest instead of Raghav's suggestion (the screen size changes with the orientation in newer APIs):

    <activity android:label="@string/app_name" 
    android:configChanges="orientation|keyboardHidden|screenSize" 
    android:name="ActivityName">
Community
  • 1
  • 1
Techwolf
  • 1,228
  • 13
  • 32
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) {

  }

}

Change it with your code. It's version issue. After version three we do not set view in main thread so we have to use async task...

Mario Kutlev
  • 4,897
  • 7
  • 44
  • 62
Digvesh Patel
  • 6,503
  • 1
  • 20
  • 34
2

In onStop of the activity dimiss the dialog. Additionally before calling dismiss check

dialog.isShowing() is true or not.

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

From the source code

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;      
    }   
}

Since you are getting this exception it means that the view is not found when dismiss is called.

Abhishek Nandi
  • 4,265
  • 1
  • 30
  • 43
2

I am quite certain that it's the Dialog that causing this issue as Chinmoy Debnath pointed out.

Nitin Sethi
  • 1,416
  • 1
  • 11
  • 19