gpt4 book ai didi

java - Android 方向更改导致应用程序崩溃

转载 作者:行者123 更新时间:2023-12-01 12:58:45 25 4
gpt4 key购买 nike

这种情况只发生过一次,但我有点担心。我正在测试更改方向的应用程序,但应用程序崩溃了。以前从未发生过,所以只是想看看其他人是否遇到过这个问题以及我可以采取什么措施来解决它。请参阅下面的日志:

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

所以对我来说,它似乎在膨胀布局方面存在问题。我不明白怎么回事,因为在崩溃之前我已经改变了大约 4 次方向。

再往下一点,有一个 java.lang.OutOfMemoryError 错误,所以我认为这导致了 android.view.InflateException

对此的任何帮助将不胜感激。谢谢

编辑:

这是崩溃的 Activity :

public class InstructionsActivity extends MenuActivity {
private ScrollView mScrollButton;
private WebView topContent;
private WebView bottomContent;
private boolean mMoreInfoTop = false;
private int mYdelta = 0;
private int mBottomOffset = 0;
private ActivityHelper activityHelper;
private boolean isPhone;
private String topHtml;
private String bottomHtml;
private String flag;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.instructions);

activityHelper = new ActivityHelper(this);
activityHelper.getScreenTag(R.id.instructions);
activityHelper.getDrawableFolder();
activityHelper.setTitleTextSize(R.string.Hearing_Test, true);
isPhone = activityHelper.isPhone();

if(isPhone){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

mScrollButton = (ScrollView) findViewById(R.id.scroll_view);
flag = String.valueOf(getIntent().getStringExtra("Flag"));

if (flag.equalsIgnoreCase("firstInstructions")) {
topHtml = this.getString(R.string.top_content);

Button startTest = (Button) findViewById(R.id.test);
startTest.setText(R.string.start_test);
}else if(flag.equalsIgnoreCase("secondInstructions")){
topHtml = this.getString(R.string.switch_file);

Button startTest = (Button) findViewById(R.id.test);
startTest.setText(R.string.continue_test);
}

bottomHtml = this.getString(R.string.bottom_content);
topContent = (WebView) findViewById(R.id.top_content);
topContent.setBackgroundColor(0);
bottomContent = (WebView) findViewById(R.id.bottom_content);
bottomContent.setBackgroundColor(0);
bottomContent.getSettings().setUseWideViewPort(false);

topContent.loadUrl("file:///android_asset/html/" + topHtml);
bottomContent.loadUrl("file:///android_asset/html/" + bottomHtml);

getMargins();

setResult(RESULT_OK);
}

public void getMargins() {

ViewTreeObserver viewTreeObserver = topContent.getViewTreeObserver();

viewTreeObserver.addOnPreDrawListener(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;
}
});
}

Runnable mAddMargin = new Runnable() {
@Override
public void run() {
try {
int marginHeight;

if (isPhone) {
marginHeight = activityHelper.getMarginHeight(R.id.more_info, R.id.bottom_content);
RelativeLayout buttonHolder = (RelativeLayout) findViewById(R.id.instructionsLayout);
mBottomOffset = buttonHolder.getBottom();
mScrollButton = (ScrollView) findViewById(R.id.scroll_view);
mYdelta = mScrollButton.getScrollY();
activityHelper.setMarginHeight(marginHeight, R.id.instructionsLayout);
} else if (!isPhone) {
// int sideMargin = activityHelper.getWebViewMargin(R.id.bottom_content);
// if(sideMargin != 0){
// activityHelper.setWebViewMargin(sideMargin, R.id.top_content);
// activityHelper.setWebViewMargin(sideMargin, R.id.bottom_content);
// }
marginHeight = activityHelper.getMarginHeight(R.id.more_info, R.id.bottom_content);
activityHelper.setMarginHeight(marginHeight, R.id.more_info);
}
} catch (Exception e) {
Log.e("Scroll View", "Couldn't run mAddMargin:", e);
}
}
};

public void onClickHandler(View aView) {

if (flag.equalsIgnoreCase("firstInstructions")) {
Intent intent = new Intent(this, HearingTestActivity.class);
startActivity(intent);
}else if(flag.equalsIgnoreCase("secondInstructions")){
finish();
}
}

public void infoView(View aView) {
Intent intent = new Intent(this, InfoActivity.class);
startActivity(intent);
}

public void onMoreInstructions(View aView) {
// Scroll the start button to the top of the screen.
mScrollButton.post(new Runnable() {

@Override
public void run() {
if (mMoreInfoTop) {
mMoreInfoTop = false;
mScrollButton.scrollTo(0, mYdelta);
} else {
mMoreInfoTop = true;
mScrollButton.scrollTo(0, mBottomOffset);
}
}
});
}
}

您需要我提供其他代码吗?

新代码:

这是我更新的代码:

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是否为空,是否删除监听器?

我的说法正确吗?谢谢

最佳答案

这看起来像是典型的内存泄漏情况。

最有可能的是,您在监听器或 Activity 中保留对某些 UI 组件(甚至可能是 AsyncTask )的实时引用。这会导致 Activity当您转动设备时,实例将被泄漏(避免被垃圾收集)——因为由于方向改变另一个 Activity实例已创建,旧实例应该被销毁并收集。

将设备转动 3 次后,您将获得所有内容的 4 个副本 - 因此出现了 OOM。

另一种可能性是您正在解码 Bitmap手动而不是调用 recycle()当您的 Activity 时就可以了已被摧毁。

是的,正如人们在评论中建议的那样,在您发布代码之前,没有什么更具体的内容。

UPD 哦,是的,现在代码已经存在,问题的根源很可能是在匿名类中的某个地方( OnPreDrawListenerRunnable )。首先,并非所有条件都能保证您的监听器被删除 - 我不确定这正是导致泄漏的原因,但请考虑检查监听器是否仍然存在并在 onDestroy() 中将其删除。还。但更一般的想法是,任何不平凡的匿名类和嵌套非静态类都是一个坏主意,因为它们存储对包含类的实例的隐式引用 - 在本例中为 Activity 。如果任何代码发生任何未预料到的情况——它可能会导致包含的实例被保留。

因此,最安全的策略是避免使用非静态嵌套(更不用说匿名)类,除非它们所承载的逻辑非常微不足道,以至于您完全确定其含义。

我的首选方法是创建静态嵌套 Listener s(或 AsyncTask s、Runnable s 等​​)通过 WeakReference 引用他们需要的一切。最明显的解决方案是存储对 Activity 的引用在成员(member)WeakReference<InstructionsActivity>并检查 null当相应的代码被执行时。如果返回null - 这意味着你的Activity被摧毁了,只是return立即。

UPD另外,请考虑使用 Eclipse MAT(here's a good article,通过 google 搜索更多信息)来检测内存泄漏。它具有在 HPROF 转储文件上运行 OQL 查询的出色能力,这样您就可以查询可疑的泄漏类( Activity 类),如果有两个或多个,您就知道有问题。它甚至会向您显示哪些对象保留了它们 - 查找GC根路径

关于java - Android 方向更改导致应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23676998/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com