Application crash after changing screen orientation

I have the following problem. After starting the application works fine - even after changing the screen orientation. The application is not yet prepared for handling orientation changes (for example, an alternative layout, etc.), therefore, only the expanded layout by default appears, and everything is in order. However, when I leave the application by pressing the back key, change the orientation and immediately after starting the application it will work again. After a crash, if I run the application again, it works well until the previously described circumstances are detected - then it will work.

I connected the device to the computer and ran the application in debug mode. After a restart, an exception is thrown even before the onCreate function is called. Collision Column:

Thread [<1> main] (Suspended (exception IllegalArgumentException)) WindowManagerImpl.removeViewImmediate(View) line: 262 Window$LocalWindowManager.removeViewImmediate(View) line: 436 ActivityThread.handleDestroyActivity(IBinder, boolean, int, boolean) line: 4022 ActivityThread.handleRelaunchActivity(ActivityThread$ActivityRecord, int) line: 4127 ActivityThread.access$2400(ActivityThread, ActivityThread$ActivityRecord, int) line: 136 ActivityThread$H.handleMessage(Message) line: 2183 ActivityThread$H(Handler).dispatchMessage(Message) line: 99 Looper.loop() line: 143 ActivityThread.main(String[]) line: 5068 Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] Method.invoke(Object, Object...) line: 521 ZygoteInit$MethodAndArgsCaller.run() line: 858 ZygoteInit.main(String[]) line: 616 NativeStart.main(String[]) line: not available [native method] 

I plan to handle the screen rotation later, but until then, I want the default behavior to work correctly.

I exceeded only the onCreate Activity method. I also have my own application class that creates an instance of the used machine class for the entire application:

 public class ProCalcApplication extends Application { private Engine engine; public ProCalcApplication() { super(); engine = new Engine(); } public Engine getEngine() { return engine; } } 

How to solve this problem?


I did some more tests. I commented all the code, leaving only the onCreate (super () + setContentLayout ()) method by default. The problem continued, so I commented on the whole XML format and the application finally stopped. I'm in the process of nailing an erroneous record, please wait :)


I found a reason, but no solution. The following is the wrong XML code:

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.gesture.GestureOverlayView android:id="@+id/gestureOverlay" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3"> <ViewFlipper android:id="@+id/contextArea" android:layout_width="match_parent" android:layout_height="match_parent"> </ViewFlipper> </android.gesture.GestureOverlayView> </LinearLayout> 

Can someone try to prove or disprove that this code does not work under the circumstances described? Or indicate where I made a mistake;)

My environment: HTC Desire Z (2.2.1), used by API 8. Eclipse version: Helios Service Release 2 Build ID: 20110218-0911.

Edit: make it a little shorter:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ViewFlipper android:id="@+id/contextArea" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3"> </ViewFlipper> </LinearLayout> 

And a little more information; API 8 in the emulator: two screen orientation changes (Ctrl + F12) and application crashes. API 10 in the emulator: two changes in screen orientation, and the screen remains in landscape mode regardless of orientation (the application does not crash, though).

What did I miss?

+4
source share
2 answers

I found out that I missed :) Since no one answered, I will leave an answer to everyone who runs into the same problem.

It turned out that the described problem is a well-known error of Android libraries: ViewFlipper does not correctly handle screen orientation changes. It appeared in API 2.1 and continues to 3.0, where it is believed to be fixed. Unfortunately, most modern smartphones suffer from this problem, as they usually have 2.2 or 2.3 on board.

The solution is to manually adjust the orientation of the screen (see Restarting activity during Android rotation ) or to implement the appearance and animation changes manually using FrameLayout to view the visibility and animation classes.

Another is to use the Eric Burke SafeViewFlipper class:

 /** * Works around Android Bug 6191 by catching IllegalArgumentException after * detached from the window. * * @author Eric Burke ( eric@squareup.com ) */ public class SafeViewFlipper extends ViewFlipper { public SafeViewFlipper(Context context) { super(context); } public SafeViewFlipper(Context context, AttributeSet attrs) { super(context, attrs); } /** * Workaround for Android Bug 6191: * http://code.google.com/p/android/issues/detail?id=6191 * <p/> * ViewFlipper occasionally throws an IllegalArgumentException after * screen rotations. */ @Override protected void onDetachedFromWindow() { try { super.onDetachedFromWindow(); } catch (IllegalArgumentException e) { Log.d(TAG, "SafeViewFlipper ignoring IllegalArgumentException"); // Call stopFlipping() in order to kick off updateRunning() stopFlipping(); } } } 

You can use it when creating a layout from the code, and also paste it into your xml layout file (you will need to fully qualify it, for example. <Com.myapp.SafeViewFlipper />).

See also http://code.google.com/p/android/issues/detail?id=6191 for more information.

+10
source

It works for you.

 package com.palewar; import android.app.Activity; import android.app.ProgressDialog; import android.os.Bundle; import android.os.Handler; import android.os.Message; public class ThreadActivity extends Activity { static ProgressDialog dialog; private Thread downloadThread; final static Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); dialog.dismiss(); } }; protected void onDestroy() { if (dialog != null && dialog.isShowing()) { dialog.dismiss(); dialog = null; } super.onDestroy(); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); downloadThread = (Thread) getLastNonConfigurationInstance(); if (downloadThread != null && downloadThread.isAlive()) { dialog = ProgressDialog.show(ThreadActivity.this, "", "Signing in...", false); } dialog = ProgressDialog.show(ThreadActivity.this, "", "Signing in ...", false); downloadThread = new MyThread(); downloadThread.start(); // processThread(); } // Save the thread @Override public Object onRetainNonConfigurationInstance() { return downloadThread; } static public class MyThread extends Thread { @Override public void run() { try { // Simulate a slow network try { new Thread().sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } handler.sendEmptyMessage(0); } finally { } } } } 
0
source

All Articles