Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setRequestedOrientation before showing ProgressDialog leads to crash

Tags:

android

I am developing an android app that should only run in portrait mode due to the layout not fitting on a phone's landscape screen. On tablets and netbooks, however, I want the app to only run in landscape mode.

I've now tried to check if the app is running on a tablet device and setting the corresponding requested orientation via setRequestedOrientation.

The problem is that the app crashes now when the device is not already held in the orientation I'm requesting, because I display a progressDialog shortly after the call to setRequestedOrientation, which seems to leak a window then.

Logcat says:

10-18 21:15:30.698: E/WindowManager(653): Activity has leaked window  com.android.internal.policy.impl.PhoneWindow$DecorView@41991418 that was originally added here
10-18 21:15:30.698: E/WindowManager(653): android.view.WindowLeaked: Activity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41991418 that was originally added here
10-18 21:15:30.698: E/WindowManager(653):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:279)
10-18 21:15:30.698: E/WindowManager(653):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
10-18 21:15:30.698: E/WindowManager(653):   at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
10-18 21:15:30.698: E/WindowManager(653):   at android.view.Window$LocalWindowManager.addView(Window.java:537)
10-18 21:15:31.888: E/WindowManager(653): Activity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41588040 that was originally added here
10-18 21:15:31.888: E/WindowManager(653): android.view.WindowLeaked: Activity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41588040 that was originally added here
10-18 21:15:31.888: E/WindowManager(653):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:279)
10-18 21:15:31.888: E/WindowManager(653):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
10-18 21:15:31.888: E/WindowManager(653):   at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
10-18 21:15:31.888: E/WindowManager(653):   at android.view.Window$LocalWindowManager.addView(Window.java:537)
10-18 21:15:34.168: E/AndroidRuntime(653):  at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:599)
10-18 21:15:34.168: E/AndroidRuntime(653):  at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:336)
10-18 21:15:34.168: E/AndroidRuntime(653):  at android.view.WindowManagerImpl$CompatModeWrapper.removeView(WindowManagerImpl.java:151)

What could I do to prevent this crash? Any help would be highly appreciated.

EDIT: As I was not able to solve this, I finally managed to edit my Layout so that it now allows usage in portrait and landscape mode.

like image 337
FD_ Avatar asked Oct 18 '12 19:10

FD_


2 Answers

Do you have any source code that you could show? That could help identify the problem.

I actually had the exact same problem. But it was only happening for some of my activities.

When the screen orientation changes, Android actually destroys and recreates the activity.

So, I had code that looked like this.

   @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        setContentView(R.layout.displayscreen);

        bottomButton = (Button) findViewById(R.id.bottomButton);
        bottomButton.setOnClickListener(bottomButtonClick);
        bottomButton.setTypeface(font);
        bottomButton.setTextSize(16);
}

See what was happening is that the view was not attached correctly to the window manager. So I decided that the oncreate was perhaps not the best spot to be doing this.

Instead I added it to my on Resume and it works. Like so:

   @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.displayscreen);

        bottomButton = (Button) findViewById(R.id.bottomButton);
        bottomButton.setOnClickListener(bottomButtonClick);
        bottomButton.setTypeface(font);
        bottomButton.setTextSize(16);
}

@Override
protected void onResume() {
    super.onResume();
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

Unfortunately this also causes the the activity to still get destroyed and recreated. Calling the onCreate and onResume twice... Not good right?

So to fix this issue. You have to add this into your android manifest for your activity.

android:configChanges="keyboardHidden|orientation"

An Example:

<activity 
    android:name="com.Test.Info.DisplayInfo"
    android:configChanges="keyboardHidden|orientation"
    android:label="@string/info">
</activity>

This code prevents the destroy/recreate cycle.

Hopefully this helps!

Cheers

like image 74
Dave Avatar answered Oct 22 '22 12:10

Dave


If you use

setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);

to temporarily lock, and

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

to unlock the screen rotation, maybe you ran into the following problem.

If you use this method to lock the screen orientation and the device is not in its default orientation, it will switch to the default orientation, destroying and creating your activity. Your app will crash, due to the fact that your trying to update some destoryed progressDialog.

like image 22
darksaga Avatar answered Oct 22 '22 12:10

darksaga