在使用VIEwPager时,Google亲爹为我们提供了多种PagerAdapter。其中,与Fragment相关的是FragmentPagerAdapter和FragmentStatePagerAdapter。对于它们的区别,网上有很多论述。在这里我们主要谈的是,在使用FragmentPagerAdapter时,Fragment生命周期方法的调用时机。
1、Activity
1 public class MainActivity extends AppCompatActivity { 2 private VIEwPager vpContent; 3 private Fragment[] fragments = new Fragment[4]; 4 5 @OverrIDe 6 protected voID onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentVIEw(R.layout.activity_main); 9 10 vpContent = (VIEwPager) findVIEwByID(R.ID.vp_content);11 fragments[0] = new Fragment1();12 fragments[1] = new Fragment2();13 fragments[2] = new Fragment3();14 fragments[3] = new Fragment4();15 16 MyAdapter adapter = new MyAdapter(getSupportFragmentManager(),fragments);17 vpContent.setAdapter(adapter);18 }19 }
2、Adapter
1 public class MyAdapter extends FragmentPagerAdapter { 2 private Fragment[] fragments; 3 4 public MyAdapter(FragmentManager fm,Fragment[] fragments) { 5 super(fm); 6 this.fragments = fragments; 7 } 8 9 @OverrIDe10 public Fragment getItem(int position) {11 return fragments[position];12 }13 14 @OverrIDe15 public int getCount() {16 return fragments.length;17 }18 }3、Fragment (4个Fragment的代码完全一致)
1 public class Fragment1 extends Fragment { 2 private static final String TAG = Fragment1.class.getSimplename(); 3 4 public Fragment1(){ 5 Log.e(TAG,"Fragment1 构造器..."); 6 } 7 8 @OverrIDe 9 public voID onAttach(Context context) {10 super.onAttach(context);11 Log.e(TAG,"onAttach...");12 }13 14 @OverrIDe15 public voID onCreate(@Nullable Bundle savedInstanceState) {16 super.onCreate(savedInstanceState);17 Log.e(TAG,"onCreate...");18 }19 20 @Nullable21 @OverrIDe22 public VIEw onCreateVIEw(LayoutInflater inflater,@Nullable VIEwGroup container,@Nullable Bundle savedInstanceState) {23 Log.e(TAG,"onCreateVIEw...");24 VIEw vIEw = inflater.inflate(R.layout.fragment1,container,false);25 return vIEw;26 }27 28 @OverrIDe29 public voID onActivityCreated(@Nullable Bundle savedInstanceState) {30 super.onActivityCreated(savedInstanceState);31 Log.e(TAG,"onActivityCreated...");32 }33 34 @OverrIDe35 public voID onStart() {36 super.onStart();37 Log.e(TAG,"onStart...");38 }39 40 @OverrIDe41 public voID onResume() {42 super.onResume();43 Log.e(TAG,"onResume...");44 }45 46 @OverrIDe47 public voID onPause() {48 super.onPause();49 Log.e(TAG,"onPause...");50 }51 52 @OverrIDe53 public voID onStop() {54 super.onStop();55 Log.e(TAG,"onStop...");56 }57 58 @OverrIDe59 public voID onDestroyVIEw() {60 super.onDestroyVIEw();61 Log.e(TAG,"onDestroyVIEw...");62 }63 64 @OverrIDe65 public voID onDestroy() {66 super.onDestroy();67 Log.e(TAG,"onDestroy...");68 }69 70 @OverrIDe71 public voID onDetach() {72 super.onDetach();73 Log.e(TAG,"onDetach...");74 }75 }三、测试数据 1、当前界面为Fragment1 打开应用主界面,日志如下:
1 06-14 14:41:09.293 22311-22311/? E/Fragment1: Fragment1 构造器... 2 06-14 14:41:09.294 22311-22311/? E/Fragment2: Fragment2 构造器... 3 06-14 14:41:09.295 22311-22311/? E/Fragment3: Fragment3 构造器... 4 06-14 14:41:09.295 22311-22311/? E/Fragment4: Fragment4 构造器... 5 06-14 14:41:09.332 22311-22311/? E/Fragment1: onAttach... 6 06-14 14:41:09.332 22311-22311/? E/Fragment1: onCreate... 7 06-14 14:41:09.332 22311-22311/? E/Fragment2: onAttach... 8 06-14 14:41:09.332 22311-22311/? E/Fragment2: onCreate... 9 06-14 14:41:09.333 22311-22311/? E/Fragment1: onCreateVIEw...10 06-14 14:41:09.335 22311-22311/? E/Fragment1: onActivityCreated...11 06-14 14:41:09.335 22311-22311/? E/Fragment1: onStart...12 06-14 14:41:09.335 22311-22311/? E/Fragment1: onResume...13 06-14 14:41:09.335 22311-22311/? E/Fragment2: onCreateVIEw...14 06-14 14:41:09.336 22311-22311/? E/Fragment2: onActivityCreated...15 06-14 14:41:09.336 22311-22311/? E/Fragment2: onStart...16 06-14 14:41:09.336 22311-22311/? E/Fragment2: onResume...
可见VIEwPager预加载了第二个Fragment,并调用其相关生命周期方法一直到onResume。如果我们在生命周期方法中都请求了网络,那么两个Fragment都请求了网络。
锁屏,日志如下:1 06-14 14:41:39.328 22311-22311/com.test.fragmentpager E/Fragment1: onPause...2 06-14 14:41:39.329 22311-22311/com.test.fragmentpager E/Fragment2: onPause...3 06-14 14:41:39.417 22311-22311/com.test.fragmentpager E/Fragment1: onStop...4 06-14 14:41:39.417 22311-22311/com.test.fragmentpager E/Fragment2: onStop...
解锁,日志如下:
1 06-14 14:44:25.512 22311-22311/com.test.fragmentpager E/Fragment1: onStart...2 06-14 14:44:25.512 22311-22311/com.test.fragmentpager E/Fragment2: onStart...3 06-14 14:44:25.513 22311-22311/com.test.fragmentpager E/Fragment1: onResume...4 06-14 14:44:25.513 22311-22311/com.test.fragmentpager E/Fragment2: onResume...
以上可知无论是锁屏、解锁,两个Fragment都调用了生命周期方法。
2、切换到Fragment2 Fragment2显示,日志如下:1 06-14 15:00:19.933 22311-22311/com.test.fragmentpager E/Fragment3: onAttach...2 06-14 15:00:19.933 22311-22311/com.test.fragmentpager E/Fragment3: onCreate...3 06-14 15:00:19.933 22311-22311/com.test.fragmentpager E/Fragment3: onCreateVIEw...4 06-14 15:00:19.937 22311-22311/com.test.fragmentpager E/Fragment3: onActivityCreated...5 06-14 15:00:19.937 22311-22311/com.test.fragmentpager E/Fragment3: onStart...6 06-14 15:00:19.938 22311-22311/com.test.fragmentpager E/Fragment3: onResume...
此时预加载了Fragment3,调用方法跟Fragment2居然没有一丝关系。
是的,你没看错。
因为该执行的都执行过了,Fragment2已经onResume了。
1 06-14 15:01:25.536 22311-22311/com.test.fragmentpager E/Fragment1: onPause...2 06-14 15:01:25.536 22311-22311/com.test.fragmentpager E/Fragment2: onPause...3 06-14 15:01:25.537 22311-22311/com.test.fragmentpager E/Fragment3: onPause...4 06-14 15:01:25.605 22311-22311/com.test.fragmentpager E/Fragment1: onStop...5 06-14 15:01:25.605 22311-22311/com.test.fragmentpager E/Fragment2: onStop...6 06-14 15:01:25.605 22311-22311/com.test.fragmentpager E/Fragment3: onStop...
解锁,日志如下:
1 06-14 15:04:20.663 22311-22311/com.test.fragmentpager E/Fragment1: onStart...2 06-14 15:04:20.663 22311-22311/com.test.fragmentpager E/Fragment2: onStart...3 06-14 15:04:20.664 22311-22311/com.test.fragmentpager E/Fragment3: onStart...4 06-14 15:04:20.666 22311-22311/com.test.fragmentpager E/Fragment1: onResume...5 06-14 15:04:20.666 22311-22311/com.test.fragmentpager E/Fragment2: onResume...6 06-14 15:04:20.666 22311-22311/com.test.fragmentpager E/Fragment3: onResume...
三个Fragment齐头并进,都调用onPause、onStop、onStart、onResume。
精彩的要来了...
1 06-14 15:16:27.252 22311-22311/com.test.fragmentpager E/Fragment4: onAttach...2 06-14 15:16:27.253 22311-22311/com.test.fragmentpager E/Fragment4: onCreate...3 06-14 15:16:27.253 22311-22311/com.test.fragmentpager E/Fragment1: onPause...4 06-14 15:16:27.253 22311-22311/com.test.fragmentpager E/Fragment1: onStop...5 06-14 15:16:27.253 22311-22311/com.test.fragmentpager E/Fragment1: onDestroyVIEw...6 06-14 15:16:27.254 22311-22311/com.test.fragmentpager E/Fragment4: onCreateVIEw...7 06-14 15:16:27.259 22311-22311/com.test.fragmentpager E/Fragment4: onActivityCreated...8 06-14 15:16:27.260 22311-22311/com.test.fragmentpager E/Fragment4: onStart...9 06-14 15:16:27.260 22311-22311/com.test.fragmentpager E/Fragment4: onResume...
哇日这是什么gui...
是的,跟Fragment3没有什么关系,又预加载了Fragment4,调用其生命周期方法到onResume。
但是也抛弃了Fragment1,调用onPause,onStop、onDestroyVIEw。
等等。。。那剩下的onDestroy、onDetach呢?
是的,它们没有执行,说明Fragment1还在,还依附在Activity上,还在内存当中。
1 锁屏,日志如下: 2 06-14 15:16:56.836 22311-22311/com.test.fragmentpager E/Fragment2: onPause... 3 06-14 15:16:56.837 22311-22311/com.test.fragmentpager E/Fragment3: onPause... 4 06-14 15:16:56.837 22311-22311/com.test.fragmentpager E/Fragment4: onPause... 5 06-14 15:16:56.895 22311-22311/com.test.fragmentpager E/Fragment2: onStop... 6 06-14 15:16:56.895 22311-22311/com.test.fragmentpager E/Fragment3: onStop... 7 06-14 15:16:56.895 22311-22311/com.test.fragmentpager E/Fragment4: onStop...
8 解锁,日志如下: 9 06-14 15:27:26.440 22311-22311/com.test.fragmentpager E/Fragment2: onStart...10 06-14 15:27:26.440 22311-22311/com.test.fragmentpager E/Fragment3: onStart...11 06-14 15:27:26.440 22311-22311/com.test.fragmentpager E/Fragment4: onStart...12 06-14 15:27:26.449 22311-22311/com.test.fragmentpager E/Fragment2: onResume...13 06-14 15:27:26.450 22311-22311/com.test.fragmentpager E/Fragment3: onResume...14 06-14 15:27:26.450 22311-22311/com.test.fragmentpager E/Fragment4: onResume...
这已经跟Fragment1没有关系了,只有2、3、4的事了。
四、结论前提是用了FragmentPagerAdapter。
1、VIEwPager总会预加载下一个Fragment,并调用其生命周期方法。
2、VIEwPager会抛弃前一个的前面的Fragment,但它仍处于内存中。
3、锁屏、解锁会调用当前未被抛弃的所有的Fragment的生命周期方法。(2个或者3个Fragment)
我们可以推论。当切换到Fragment4时:
1、预加载没有了,因为没有下一个Fragment。
2、Fragment2被抛弃,调用其onPause、onStop、onDestroyVIEw方法。
3、锁屏、解锁只会调用Fragment3、Fragment4的相应生命周期方法。
那对于FragmentStatePagerAdapter呢?经过测试,其生命周期方法调用时机与使用FragmentPagerAdapter的区别在于VIEwPager抛弃前一个的前面的Fragment时,会调用onDestroy、onDetach方法,而再次预加载时,重新调用onAttach、onCreate方法。
总结以上是内存溢出为你收集整理的Fragment生命周期函数调用(ViewPager切换方式)全部内容,希望文章能够帮你解决Fragment生命周期函数调用(ViewPager切换方式)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)