Android ViewPager+Fragment生命週期優化

一.頁面緩存

ViewPager默認會緩存1~2個頁面,也就是當前頁面的前一個頁面和後一個頁面,若是後一個頁面不存在,則不在緩存,反之會被緩存java

offscreenPageLimit的默認值爲1android

         int offscreenPageLimit =  mViewPager.getOffscreenPageLimit();
         Log.e("MainActivity", "offscreenPageLimit="+offscreenPageLimit);

1.1輪播圖緩存

有時,須要使用ViewPager+反射勻速Scroller+ImageView作輪播圖時,輪播的圖片超過4個就會出現空白的問題,對於這種問題,明細咱們須要把offscreenPageLimit設置爲n-1,(n爲圖片的個數),這樣把圖片緩存起來(輪播圖通常在首頁,長期存在,所以也就不要想着及時釋放掉這幾張圖片了)性能優化

mViewPager.setOffscreenPageLimit(imageList.size()-1);
二. 當前視圖Fragment更新

ViewPager+Fragment也會受到offscreenPageLimit的影響,對於這個,建議使用n-1模式app

   List<BaseFragment> fragmentList = Collections.synchronizedList(new ArrayList<BaseFragment>());
         fragmentList.add((BaseFragment) BaseFragment.instantiate(this, CommonFragment.class.getName(), createBuddle(0)));
         fragmentList.add((BaseFragment) BaseFragment.instantiate(this, CommonFragment.class.getName(), createBuddle(1)));
         fragmentList.add((BaseFragment) BaseFragment.instantiate(this, CommonFragment.class.getName(), createBuddle(2)));
         mViewPager.setAdapter(new ViewPagerFragmentAdapter(getSupportFragmentManager()));
         //CommonFragment是BaseFragment的子類
         mViewPager.setOffscreenPageLimit(fragmentList.size()-1);
         mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
        	 @Override
        	public void onPageSelected(int position) {
        		super.onPageSelected(position);
        		BaseFragment fragment = (BaseFragment) getSupportFragmentManager().getFragments().get(position);
        		fragment.updateFragment();
        	 }
         });

固然問題來了,如何每次更新呢,對於這個問題,咱們的解決方案是在BaseFragment中添加以下2個方法以及變量isFirst ide

private boolean isFirst = true;

public void updateFragment()
{
	if(isFirst)
	{
		isFirst = false;
		List<Fragment> fragments = getFragmentManager().getFragments();
		if(fragments.indexOf(this)!=0) //若是是第一個頁面,第一次調用
		{
				return;
		}
	}
	if(getView()==null)
	{
		View decorView = null;
		if(getActivity()!=null)
		{
			decorView = getActivity().getWindow().getDecorView();
		}
		if(decorView!=null)
		{
		   decorView.postDelayed(new Runnable() {
			@Override
			public void run() {
				updateFragment();
				}
				}, 100);
			}
		}else{
			onRestart();
		}
	}
	
	protected void onRestart()
	{
		
	}

這樣咱們在BaseFragment的子類中重寫onRestart()便可,onRestart在第一次不會調用,這樣就避免了onCreate和onRestart()同時調用一個接口post

三.FragmentPagerAdapter與FragmentStatePagerAdapter性能優化

如上是一張Fragment生命週期圖,其實不是很完整在 onCreateView---->onStart之間應該是性能

onCreateView->onViewCreated->onActivityCreated->onViewStateRestored->onStart優化

按照咱們Fragment的優化方案,應該分2類優化this


第一類優化(重點改善頁面少,內存,性能要求高的需求)

當咱們使用FragmentTabHost,FragmentPagerAdapter,FragmentTransaction中非replace操做的時候,咱們的優化須要參考

Android Fragment的生命週期和Inflate優化


第二類優化(重點改善頁面多,內存,性能要求高的需求)

當咱們使用的是FragmentStatePagerAdapter或者,FragmentTransaction中的replace操做,咱們須要注意,在生命週期中的

onSaveInstance<------>onViewStateRestored

2個方法,解決咱們開發中,對於頁面不肯定或者頁面較多的問題,相似Activity中的onSaveInstance和onRestoreInstance的用法,經過這種方法,來提升咱們的效率。


四.setUserVisibleHint空指針問題的解決
android.support.v4.app.Fragment.setUserVisibleHint null pointer on app resuming
android.support.v4.app.Fragment.setUserVisibleHint in Fragment.java on Line 819
android.support.v4.app.FragmentPagerAdapter.setPrimaryItem in FragmentPagerAdapter.java on Line 130

對於如上問題,咱們須要FragmentStatePagerAdapter替換FragmentPagerAdapter

相關文章
相關標籤/搜索