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

相关文章
相关标签/搜索