1

我在我們的應用程序中使用V4支持庫,並且我在正常情況下工作正常的應用程序中有一個基於步驟的過程。但是,我們有一個要求,即一切都需要工作,而不是在內存壓力情況下崩潰。所以我使用SetAlwaysFinish庫來幫助解決這個問題(https://github.com/bricolsoftconsulting/SetAlwaysFinish)。這對於確定需要檢測和處理這些情況的區域非常有幫助,但是我碰到了一個讓我難以置信的問題。請記住,這在一般情況下工作正常,但我明確測試「setAlwaysFinish」= ON。Android - 內存壓力與ViewPager崩潰>片段>活動

這是我的設置:我有一個「ProcessActivity」類,承載ViewPager的佈局。 ViewPager有一個適配器集,其中包含我將包含該過程的片段列表。這是在onCreate()方法:

ProcessActivity

createSteps(); // this creates/populates the ArrayList "processSteps" with Fragments 
theAdapter = new ProcessAdapter(this, processSteps); // the ProcessAdapter class extends FragmentStatePagerAdapter, with an additional list of Fragment steps 
theViewPager.setAdapter(theAdapter); 

還有其他的作品,但畢竟是它是如何設置的核心。在其中一個片段步驟中,我實際上需要從步驟過程中「暫停」並臨時推出一個活動來執行一些邏輯(然後再返回到步驟過程)。我這樣做如下,以ForResult,因爲我需要能夠處理的OK /在活動取消操作,當它完成:

Step4Fragment

Intent intent = new Intent(getActivity(), ThePushActivity.class); 
intent.putExtra(blah..); 
startActivityForResult(intent, THE_REQCODE); 

一旦它推到這個視圖,有時會調用ProcessActivity和Step4Fragment的onDestroy()方法(由於alwaysFinish)。有時候它看起來工作正常,它會回到Step-Fragment過程。但通常情況下,它會調用ProcessActivity的onDestroy()方法,然後它將重新調用帶有已保存實例狀態的bundle的onCreate()方法。這將調用上面的步驟創建代碼,它將應用程序置於用戶所在的最後一步顯示的時髦狀態,但在幕後它實際上是第一步(片段在這一點上已經不在重擊和斷開連接),並且不可避免地發生崩潰。看起來在這一點上,Step4Fragment是完全不連貫的,如果你試圖做任何事情,它會崩潰在某個地方,儘管看起來好像它已經被正確地重新實例化了。

有關解決這個問題的最佳方法的任何想法?我認爲如果我找到一種方法即使只是重置事件,以便在發生內存問題時將用戶踢回到流程的第一步,也沒關係。但是,當然,我的整個擔憂是崩潰。

讓我知道是否需要提供更多細節。預先感謝任何幫助!

更新#1: 只是一個快速更新,我已經注意到,碎片被重新實例化和初始化,並適當屬於「當前」片段的onActivityResult()方法和做什麼它需要做得很好。看起來斷開所在的位置在基本ProcessActivity類中,遵循以下其中一種方案。 ViewPager佈局顯示正確,但ViewPager外部的所有內容都不正確(即,它表示它在進程的第一步,當它指示它在第四步,並且導航按鈕顯示爲第一步而不是第四)。

所以我猜我需要以某種方式手動正確設置這些元素。在深入挖掘這一點的過程中,我可能會遺漏某些人需要的代碼來積極幫助解決這個問題。如果我能以某種方式訪問​​ViewPager字段的狀態,該字段可以在調用完整的onDestroy()/ onCreate()之前獲取「當前顯示的片段」,可能來自savedInstanceState包?這可能會解決我的問題。但是從調試時檢查這個包,我幾乎只能看到碎片本身以及它們各自的狀態。不過,我會繼續挖掘。

無論如何,請讓我知道,如果任何人有任何想法應該如何適當地完成這種事情(當然在高層次上)。

更新#2 我看到,即使壽「當前」片段似乎是正確的開始,視圖正確顯示,一切都脫離。我無法在getResources()或getActivity()等方法上調用任何方法。實際上,我可以基於將步驟索引(int)保存到savedInstanceState包中,然後重新加載UI來正確獲得ProcessActivity的「正常工作」元素在它周圍。不過,即使它正在被正確地重新實例化,我仍然有當前Fragment與Activity分離的阻塞器。

更新#3 當我按照這個帖子的方向:ViewPager and fragments — what's the right way to store fragment's state?,我結束了一個即時異常當我嘗試做的第一putFragment()。例外情況是:「IllegalStateException:片段Step4Fragment當前不在FragmentManager中」。我認爲這可能與這樣一個事實有關,即我在任何時候只將一個片段保留在左邊,並且一個片斷保持「活動」(即offScreenPageLimit)。

回答

0

事實證明,要解決此相似,在這篇文章中提出的解決方案:ViewPager and fragments — what's the right way to store fragment's state?

我不得不去上需要改變幾件事情。首先,我需要將碎片移至字段而不是臨時變量。其次,我需要避免每次在onCreate()中實例化新的碎片。相反,它應該嘗試從savedInstanceState拉他們這樣:

fragment1 = (Fragment1Step) getSupportFragmentManager().getFragment(savedInstanceState, Fragment1Step.class.getName()); 
fragment2 = (Fragment2Step) getSupportFragmentManager().getFragment(savedInstanceState, Fragment2Step.class.getName()); 
etc... 

,然後在此之後吧,我對他們每個人的後續檢查;如果他們是空(即新鮮的未來,而不是從保存的情況下),那麼他們將被新的實例:

if (fragment1 == null) { 
    fragment1 = new Fragment1Step(); 
} 
if (fragment2 == null) { 
    fragment2 = new Fragment2Step(); 
} 

爲了這個工作,當然,這些也應該在的onSaveInstanceState保存關閉()方法:

try { 
    getSupportFragmentManager().putFragment(outState, Fragment1Step.class.getName(), fragment1); 
} catch (Exception e) { 
    // do nothing 
} 
try { 
    getSupportFragmentManager().putFragment(outState, Fragment2Step.class.getName(), fragment2); 
} catch (Exception e) { 
    // do nothing 
} 
etc... 

我之所以在try/catch塊有這些是因爲我們的ViewPager只有1的offScreenPageLimit,所以其中的一些將在該「putFragment()」拋出異常調用,如果他們目前不在當前顯示的「活動」堆棧碎片中。

這不是非常漂亮,可能有更好的方法來處理這個..但這似乎現在正常工作正常。

0

你確定你的Fragment不是re-instantiated

Fragment的所有子類都必須包含一個公共的空構造函數。框架通常會在需要時重新實例化一個片段類,特別是在狀態恢復期間,並且需要能夠找到這個構造器來實例化它。如果空的構造函數不可用,則在狀態恢復期間會發生運行時異常。

+0

是的,所有的碎片都被重新實例化了,它們都有公共的空構造函數。我把日誌放在它們中的每一箇中,並且每個都被調用(它們都在我的文章中提到的createSteps()方法中實例化,在主流程類的onCreate()中設置它。所以它們肯定會被重新調用)。奇怪的是,從日誌看來,一切準備妥當並被調用以便重新設置視圖的位置。但實際上,如果您做了任何事情,它不會正確顯示並導致崩潰之後它顯示。 – svguerin3

+0

實現更多的日誌記錄後,我意識到它確實首先調用空構造函數(這是實際應該使用的,帶有非null連接的Activity)。但是,當ProcessActivity類的onCreate()在此之後被調用時,它會重新創建片段,看起來是不相關的片段。我很好奇我如何訪問由系統正確重新實例化的「真實」片段,在完成之後從ProcessActivity類中進行訪問。我嘗試了很多不同的東西,但我沒有太多的運氣。 :( – svguerin3

+0

@ svguerin3通過我的個人資料聯繫我,如果你願意,我會盡力幫助你通過Skype。 –