3

這是我的設置。當應用程序繼續時在列表數據上保存狀態

我有一個主SherlockFragmentActivity。它用FragmentTransaction來回交換了很多ListFragments。爲了指示載荷,隨時隨地一ListFragment加載我調用數據:

setSupportProgressBarIndeterminateVisibility(true); 

的問題:當上面提到第一啓動,或在用戶離開主Activity,去到其他的應用程序,然後重新啓動

這一個時間延長的時間之後,SherlockFragmentActivity看似重新加載,則在ActionBar沒有進展對話,屏幕是白色幾秒鐘,然後將列表數據維修(長度取決於所述數據連接上)。

下面是一些補充代碼:當主/基Activity首次加載,這是第一件事情我在onCreate()操作之一:

// Set up Main Screen 
FragmentTransaction t2 = this.getSupportFragmentManager().beginTransaction(); 
SherlockListFragment mainFrag = new FollowingFragment(); 
t2.replace(R.id.main_frag, mainFrag); 
t2.commit(); 

FollowingFragment是一個將永遠在這種情況下加載。它包含一個ListView和一個AsyncTaskMySQL數據庫中提取數據。

我的問題:如何防止這種延遲?當用戶長時間離開時,如何處理數據維護?

回答

3

這是正常的行爲,它是因爲你的活動已被殺害保存的其他應用程序的內存,當你的應用程序是在後臺。當它回到前臺時,系統重新創建您的活動,這將重新創建您的片段。

但是,如果你真的想避免重新創建你的片段,您可以在片段的onCreate方法使用setRetainInstance:

公共無效setRetainInstance(布爾保留)

控制片段實例是否可以通過保留活動重新創建(例如從配置更改)。這隻能用於不在後端堆棧中的碎片。如果設置,則在重新創建活動時,片段生命週期將略有不同:

onDestroy()將不會被調用(但onDetach()仍然會存在,因爲該片段正從當前活動中分離出來)。 由於片段未被重新創建,因此onCreate(Bundle)將不會被調用。 onAttach(Activity)和onActivityCreated(Bundle)仍然會被調用。

而且使用這樣在你FragmentActivity的onActivityCreated方法:

@Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     FragmentManager fm = getFragmentManager(); 

     // Check to see if we have retained the worker fragment. 
     mRetainableFragment = (RetainedFragment)fm.findFragmentByTag("fragmentTag"); 

     // If not retained (or first time running), we need to create it. 
     if (mRetainableFragment == null) { 
      mRetainableFragment = new RetainedFragment(); 
      // Tell it who it is working with. 
      mRetainableFragment.setTargetFragment(this, 0); 
      fm.beginTransaction().add(mRetainableFragment, "fragmentTag").commit(); 
     } 
    } 

但要注意的是,這應該只是使用了無頭片段(無UI片段,即onCreateView返回null,又名工人分段)。儘管你仍然可以使用這個方法作爲UI片段,但它不是由Google推薦的,在這種情況下,數據必須作爲成員(字段)存儲在您的活動中。如果應該存儲的數據受Bundle類支持,則可以使用onSaveInstanceState()方法將數據放入Bundle中,然後在onActivityCreated()方法中檢索該數據。

此外,這隻適用於碎片沒有添加到後臺堆棧。

+0

是的,這是一個UI'片段'。所以我想我需要使用'onSaveInstanceState()'方法。你將如何使用它並保存列表數據?該清單由一份「清單」組成。 – KickingLettuce

+0

我通常將我的數據存儲在一個經理(單身人士),我可以從任何地方獲得它。這樣我就不需要保存UI實例狀態。否則,您可以輕鬆地存儲您的List,因爲它實現了可序列化,只需確保您的對象類,然後在要保存的包中使用putSerializable方法即可。 – Gomino

1

按照Android developer reference page on Activity,你必須調用setSupportProgressBarIndeterminateVisibility()之前請求進度欄功能:

requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 
setContentView(R.layout.activity_main); 
setSupportProgressBarIndeterminateVisibility(true); 

的另一個問題,重裝的片段,是由於Android的殺死你ListFragment,使他們不得不重新加載可能通過覆蓋onSaveInstanceState(Bundle outState)並緩存在那裏,你的數據被解析爲您ListFragment檢索:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    if(savedInstanceState != null) { 
     // retrieve data from Bundle here 
    } else { 
     // no data, we need to reload from network 
    } 

    // initialize your View here 
} 

此方法不能保證(但它並不在碎片生命週期中)。因此,您還應確保將數據緩存在onPause()中,並使用它,而不是始終從網絡連接加載。

@Override 
public void onPause() { 
    super.onPause(); 
    SharedPreferences prefs = getActivity().getSharedPreferences(); 
    SharedPreferences.Editor editor = prefs.edit(); 
    // put your data here using editor 
    editor.commit(); 
} 

然後你就可以通過檢索的SharedPreferences一個實例,並使用prefs.getString(String key)等方法在onCreateView()加載這些數據。

0

當您在延長一段時間後返回到活動狀態時,整個應用程序將重新啓動。所以你不能依賴對象變量來保存數據。

所以你可以避免延遲你已經提到將數據保存到活動onStop()方法中的某些本地存儲。例如,共享首選項。

當您調用onCreate()時,檢查是否保存了數據並在存在時使用它(並清理以便下次啓動「clean」),否則請啓動asynctask。

1

當你的應用程序死亡,你失去了你的活動狀態和數據!有兩種情況可以假設您的AsyncTask
1.您從Webserver中提取一些數據。在這種情況下,我個人認爲緩存從webserver檢索到的數據是比實施serializable更好的解決方案。
2.您正在從本地數據庫中提取大量數據(這會導致檢索數據需要一些時間)。在這種情況下,我建議只檢索儘可能多的數據,而不是更多! (例如,您可以檢索20個項目,並且當用戶滾動到ListView的末尾時檢索接下來的20個項目)。 該解決方案可幫助您的應用程序更快地檢索數據。

PS:給你一個線索如何實現WebserviceModule與緩存能力,我以爲是位於您AsyncTask,可以節省從webserver在SD卡每次你正在嘗試從webserver一些資源的時間每個響應和,你應該檢查SDCard,看看你的請求是否已經發送和緩存!對於每一個請求,您都應該在urlpost parameters上創建一個唯一的簽名庫來識別緩存的文件。

相關問題