屏幕方向更改后应用程序崩溃
我遇到以下问题。启动后,即使在更改屏幕方向后,应用程序也能正常工作。应用程序尚未准备好处理方向更改(例如,替代布局等),因此只需旋转默认布局即可出现,并且没问题。但是,当我按下后退键退出应用程序时,请改变方向,并在再次启动应用程序后立即崩溃。在崩溃之后,如果我再次启动应用程序,它会很好地工作,直到之前描述的情况发生 - 然后它崩溃。屏幕方向更改后应用程序崩溃
我已将设备连接到计算机并以调试模式运行应用程序。重新启动后,即使在调用onCreate之前也会引发异常。崩溃callstack如下:
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]
我打算稍后处理屏幕旋转,但在此之前,我希望默认行为正常工作。
我只覆盖了onCreate Activity的方法。我也有自定义应用程序类,它创建了应用程序范围内使用的引擎类的实例:
public class ProCalcApplication extends Application
{
private Engine engine;
public ProCalcApplication()
{
super();
engine = new Engine();
}
public Engine getEngine()
{
return engine;
}
}
如何解决此问题?
我已经做了一些更多的测试。我已经注释掉了整个代码,只留下了onCreate方法(super()+ setContentLayout())的默认实现。问题依然存在,所以我已经评论了整个布局XML,并且应用程序最终停止了崩溃。我正在处理错误的输入,请耐心等待)
我找到了原因,但没有解决方法。出故障的XML代码如下:
<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>
有人可以也许试图证明或反驳,该代码中所描述的情况下失败了呢?或者指出,我在哪里犯了一个错误;)
我的环境:HTC Desire Z(2.2.1),使用API 8。 Eclipse版本:Helios Service Release 2 Build ID:20110218-0911。
编辑:让它短一点:
<?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>
,多一点信息;仿真器中的API 8:两个屏幕方向更改(Ctrl + F12)和应用程序崩溃。仿真器中的API 10:两个屏幕方向更改,屏幕保持横向模式,而不管方向如何(应用程序不会崩溃)。
我错过了什么?
我发现了,我错过了什么:)因为没有人回答,我会为每个人留下一个答案,谁会遇到同样的问题。
事实证明,所描述的问题是一个众所周知的Android库错误:ViewFlipper无法正确处理屏幕方向更改。它已经出现在API 2.1中,一直持续到3.0,它被认为是固定的。不幸的是,今天的大多数智能手机都会遇到这个问题,因为它们通常板载2.2或2.3。
解决方案是手动处理屏幕方向更改(请参阅Activity restart on rotation Android),或者使用FrameLayout手动实现视图更改和动画,查看可见性和动画类。
另一种是用埃里克·伯克SafeViewFlipper类:
/**
* Works around Android Bug 6191 by catching IllegalArgumentException after
* detached from the window.
*
* @author Eric Burke ([email protected])
*/
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();
}
}
}
您可以使用它在创建从代码的布局,以及将它嵌入到XML布局文件(你必须限定它完全,例如,< com.myapp.SafeViewFlipper/>)。
另请参阅http://code.google.com/p/android/issues/detail?id=6191了解更多信息。
我发现它停止引发此异常。该错误已经得到了解决。 Android 7.1.2,小米redmi 4x,miui全球8.5 – Sergio 2017-11-17 11:13:15
本工程为您
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 {
}
}
}
}
你跟测试什么设备?什么API级别?你有没有注意到你的引擎类是否正在重新初始化后定向更改启动?应该吗,还是不应该? – 2011-05-03 12:28:33
HTC Desire Z. API级别8.在方向更改重新启动后,引擎未重新初始化;它不应该这样做,但如果它没有坏处(尽管性能下降很小)。 – Spook 2011-05-03 12:40:48
您是否在重新启动时检查引擎是否为空?另外,您是否将ProCalcApplication专门注册为清单中应用程序的扩展? – 2011-05-03 13:53:19