Java Android方向改变导致应用程序崩溃
这只发生过一次,但我有点担心。我在测试应用程序时改变了方向,应用程序崩溃了。以前从未发生过,所以只想看看是否有其他人有过此问题,以及我能做些什么来解决它。请参阅以下日志:Java Android方向改变导致应用程序崩溃,java,android,Java,Android,这只发生过一次,但我有点担心。我在测试应用程序时改变了方向,应用程序崩溃了。以前从未发生过,所以只想看看是否有其他人有过此问题,以及我能做些什么来解决它。请参阅以下日志: 05-15 12:13:07.304: E/AndroidRuntime(2596): FATAL EXCEPTION: main 05-15 12:13:07.304: E/AndroidRuntime(2596): java.lang.RuntimeException: Unable to start activity
05-15 12:13:07.304: E/AndroidRuntime(2596): FATAL EXCEPTION: main
05-15 12:13:07.304: E/AndroidRuntime(2596): java.lang.RuntimeException: Unable to start activity ComponentInfo{com./.hearing.InstructionsActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class <unknown>
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3740)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.app.ActivityThread.access$700(ActivityThread.java:141)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.os.Handler.dispatchMessage(Handler.java:99)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.os.Looper.loop(Looper.java:137)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.app.ActivityThread.main(ActivityThread.java:5103)
05-15 12:13:07.304: E/AndroidRuntime(2596): at java.lang.reflect.Method.invokeNative(Native Method)
05-15 12:13:07.304: E/AndroidRuntime(2596): at java.lang.reflect.Method.invoke(Method.java:525)
05-15 12:13:07.304: E/AndroidRuntime(2596): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
05-15 12:13:07.304: E/AndroidRuntime(2596): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
05-15 12:13:07.304: E/AndroidRuntime(2596): at dalvik.system.NativeStart.main(Native Method)
05-15 12:13:07.304: E/AndroidRuntime(2596): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class <unknown>
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.view.LayoutInflater.createView(LayoutInflater.java:620)
05-15 12:13:07.304: E/AndroidRuntime(2596): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:669)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:694)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
05-15 12:13:07.304: E/AndroidRuntime(2596): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:267)
05-15 12:13:07.304: E/AndroidRuntime(2596): at com.actionbarsherlock.internal.ActionBarSherlockNative.setContentView(ActionBarSherlockNative.java:133)
05-15 12:13:07.304: E/AndroidRuntime(2596): at com.actionbarsherlock.app.SherlockActivity.setContentView(SherlockActivity.java:229)
05-15 12:13:07.304: E/AndroidRuntime(2596): at .InstructionsActivity.onCreate(InstructionsActivity.java:40)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.app.Activity.performCreate(Activity.java:5133)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
05-15 12:13:07.304: E/AndroidRuntime(2596): ... 12 more
05-15 12:13:07.304: E/AndroidRuntime(2596): Caused by: java.lang.reflect.InvocationTargetException
05-15 12:13:07.304: E/AndroidRuntime(2596): at java.lang.reflect.Constructor.constructNative(Native Method)
05-15 12:13:07.304: E/AndroidRuntime(2596): at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.view.LayoutInflater.createView(LayoutInflater.java:594)
05-15 12:13:07.304: E/AndroidRuntime(2596): ... 26 more
05-15 12:13:07.304: E/AndroidRuntime(2596): Caused by: java.lang.OutOfMemoryError
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:503)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:356)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:800)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.content.res.Resources.loadDrawable(Resources.java:2105)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.widget.ImageView.<init> (ImageView.java:127)
05-15 12:13:07.304: E/AndroidRuntime(2596): at android.widget.ImageView.<init>(ImageView.java:117)
05-15 12:13:07.304: E/AndroidRuntime(2596): ... 29 more
你还需要我给你其他的密码吗
新代码:
这是我的更新代码:
public void getMargins() {
ViewTreeObserver viewTreeObserver = topContent.getViewTreeObserver();
x = new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
int topHeight = topContent.getMeasuredHeight();
int bottomHeight = bottomContent.getMeasuredHeight();
if (isPhone) {
if (topHeight != 0) {
Log.d("Web View Height", "Continue Height: "
+ topHeight);
if (mScrollButton != null) {
RelativeLayout instructions = (RelativeLayout) findViewById(R.id.more_info);
instructions.post(mAddMargin);
topContent.getViewTreeObserver()
.removeOnPreDrawListener(this);
}
topContent.getViewTreeObserver()
.removeOnPreDrawListener(this);
}
} else if (!isPhone) {
if (topHeight != 0 && bottomHeight != 0) {
Log.d("Web View Height", "top Height: " + topHeight
+ "bottom height:" + bottomHeight);
RelativeLayout instructions = (RelativeLayout) findViewById(R.id.more_info);
instructions.post(mAddMargin);
topContent.getViewTreeObserver()
.removeOnPreDrawListener(this);
}
}
return false;
}
};
viewTreeObserver.addOnPreDrawListener(x);
}
现在,我将侦听器保存到一个变量x
onDestroy方法:
@Override
protected void onDestroy() {
super.onDestroy();
if(x != null){
topContent.getViewTreeObserver()
.removeOnPreDrawListener(x);
}
}
然后检查变量x
是否为空,如果为空,是否删除侦听器
我说的对吗?谢谢这看起来像是典型的内存泄漏情况 最有可能的情况是,您正在侦听器中保留对某个UI组件(甚至可能是
活动
)的实时引用,或者异步任务
,这会导致活动
实例泄漏(防止被垃圾收集)当你转动设备时——因为方向改变,另一个活动
实例被创建,旧的实例应该被销毁和收集
转动设备3次后,所有内容都有4份拷贝——因此OOM
另一种可能是,当活动
被销毁时,您正在手动解码位图
,而没有对其调用recycle()
是的,正如大家在评论中所建议的,在你发布代码之前,没有什么更具体的东西可以说
UPD哦,是的,既然代码已经存在,那么问题的根源很可能是匿名类中的某个地方(onpredrawstener和Runnable
)。首先,并不是所有的条件都保证了你的侦听器被删除——我不确定这正是导致泄露的原因,但是考虑检查侦听器是否还在,并在代码< OnDebug()/<代码>中删除它。但更一般的想法是,任何非永久匿名和嵌套的非静态类都不是好主意,因为它们存储对包含类实例的隐式引用——在本例中是活动
。如果这些代码中有任何未预料到的情况发生,则可能会导致保留包含的实例
所以,最安全的策略是避免使用非静态嵌套(更不用说匿名)类,除非它们所携带的逻辑非常简单,以至于您完全确定其含义
我的方法是创建静态嵌套的Listener
s(或AsyncTask
s、Runnable
s等),通过WeakReference
引用所需的所有内容。最明显的解决方案是将对活动的引用
存储在成员WeakReference
中,并在执行相应的代码时检查它是否为null
。如果它返回null
——这意味着您的活动
已被破坏,请立即返回
UPD
此外,考虑使用Eclipse Mat(谷歌围绕更多)来检测内存泄漏。它具有在HPROF转储文件上运行OQL查询的强大功能,通过这种方式,您可以查询可疑的泄漏类(活动类),如果有两个或两个以上的泄漏类,您知道您有问题。它甚至会向您显示保留它们的对象--查找GC根目录的路径这可能是配置更改的原因在活动内的mainifest文件中添加以下属性。您可以根据需要进行更改
android:configChanges="orientation|screenSize|keyboard|screenLayout"
原因:java.lang.OutOfMemoryError
。在任何地方都有图像作为背景吗?你需要缩小图像的比例发布一些代码,你的某个地方有漏洞,所以我添加了它崩溃的活动中的代码。我确实有一个背景图像,我把它放在ImageView
中,我刚刚注意到在我的getMargins()
方法中有topContent.getViewTreeObserver().removeOnPreDrawListener(这个)代码>两次,这可能与此有关吗?我刚刚从崩溃的活动中添加了一些代码。您还需要什么吗?您好,感谢更新,这似乎是唯一符合逻辑的事情,我一直在尝试复制错误,但似乎无法执行,我如何检查onpredrawstener()
方法是否为空?我现在正在将它保存到一个变量中。我是否只需检查变量是否为null并使用topContent.getViewTreeObserver().removeOnPreDrawListener(变量)代码>方法并将其删除?抱歉,现在没有太多时间。只需将OnPreDrawListener存储为活动的成员变量。注销时,将其设置为null
。在onDestroy()
中检查它是否为空,如果不是--取消注册并设置为null
没问题,谢谢你的帮助,伙计,我已经用我的新代码更新了这个问题,如果你有时间,看看你的想法。感谢阿加尼希望它重新绘制布局,因为我有一个不同的布局景观,然后我做肖像。但是,我可以使用onCOnfigurationChange
方法重新绘制正确的布局?
android:configChanges="orientation|screenSize|keyboard|screenLayout"