簡體   English   中英

Android方向更改導致應用程序崩潰

[英]Android Orientation change results in app crashing

這只發生過一次,但我對此有點擔心。 我正在測試更改方向的應用程序,並且應用程序崩潰了。 以前從未發生過,所以只想看看是否有人遇到過此問題,以及我可以做些什么來解決它。 請查看以下日志:

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

任何幫助將不勝感激。 謝謝

編輯:

這是它崩潰的活動:

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是否為null,是否將其刪除監聽器?

我對此是否正確? 謝謝

這看起來像是經典的內存泄漏情況。

最有可能的是,您在監聽器或AsyncTask中保留了對某個UI組件(甚至是Activity )的實時引用,這會在您打開設備時導致Activity實例泄漏( 避免被垃圾回收 ),因為由於方向改變,將創建另一個Activity實例,並且應該將舊的Activity實例銷毀並收集。

將設備旋轉3次后,您將擁有所有內容的4個副本-因此是OOM。

另一種可能性是您要手動解碼Bitmap ,並且在Activity被銷毀時不對其調用recycle()

是的,正如伙計們在評論中所建議的那樣,在發布代碼之前,還不能說出更具體的內容。

UPD哦,是的,現在已經有了代碼,問題的根源很可能在匿名類中( OnPreDrawListenerRunnable )中。 首先,並非所有條件都能確保您的監聽器被刪除-我不確定這是否是導致泄漏的原因,但是請考慮檢查監聽器是否仍在周圍,並在onDestroy()中將其刪除。 但是更籠統的想法是,任何非私有的匿名和嵌套非靜態類都是一個壞主意,因為它們存儲對包含類的實例(在本例中為Activity的隱式引用。 如果任何意外的代碼發生了任何事情-它可能導致包含實例被保留。

因此,最安全的策略是避免使用非靜態嵌套(更不用說匿名)類了,除非它們所攜帶的邏輯是如此瑣碎,以至於您對所涉及的問題絕對有把握。

我的AsyncTask方法是創建靜態嵌套的Listener (或AsyncTaskRunnable等),它們通過WeakReference其所需的所有內容。 最明顯的解決方案是將對Activity的引用存儲在成員WeakReference<InstructionsActivity>並在執行相應的代碼時檢查是否為null 如果返回null這意味着您的Activity被銷毀,請立即return

UPD另外,請考慮使用Eclipse MAT( 這是一篇不錯的文章 ,有關更多信息,請訪問google)來檢測內存泄漏。 它具有在HPROF轉儲文件上運行OQL查詢的強大功能,通過這種方式,您可以查詢可疑的泄漏類(活動類),以及是否存在兩個或多個泄漏類-您知道您有問題。 它甚至還會向您顯示哪些對象可以保留它們-查找GC根目錄的路徑

這可能是配置更改的原因,在活動內的mainifest文件中添加以下屬性。您可以根據需要進行更改

android:configChanges="orientation|screenSize|keyboard|screenLayout"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM