一道面试题:Activity是如何实现LifecycleOwner的? - Go语言中文社区

一道面试题:Activity是如何实现LifecycleOwner的?



我们都知道Activity可作为LifecycleOwner为LiveData的使用提供条件,那么Activity是如何实现LifecycleOwner的呢?

Activity虽然实现了LifecycleOwner接口,但是并没有实现相关处理,而是通过添加一个Fragment来代理Lifecycle的分发。这种通过Fragment代理Activity行为的设计在其他一些库也经常出现,相对来说更加无侵和优雅。

SupportActivity

Activity通过继承SupportActivity实现LifecycleOwner接口。注意在AndroidX中SupportActivity改名为ComponentActivity

  1. public class SupportActivity extends Activity implements LifecycleOwner { 
  2.  
  3.     ... 
  4.  
  5.     private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); 
  6.  
  7.     ... 
  8.  
  9.     @Override 
  10.     protected void onSaveInstanceState(Bundle outState) { 
  11.         mLifecycleRegistry.markState(Lifecycle.State.CREATED); 
  12.         super.onSaveInstanceState(outState); 
  13.     } 
  14.  
  15.     ... 
  16.  
  17.     @Override 
  18.     public Lifecycle getLifecycle() { 
  19.         return mLifecycleRegistry; 
  20.     } 

SupportActivity声明了mLifecycleRegistry对象,但是没有直接使用其进行生命周期的分发,而是被ReportFragment通过activity.getLifecycle()获取使用。

ReportFragment

SupportActivity在onCreate为自己添加了ReportFragment:

  1. @RestrictTo(LIBRARY_GROUP) 
  2. public class SupportActivity extends Activity implements LifecycleOwner { 
  3.   // ... 
  4.  
  5.   @Override 
  6.   @SuppressWarnings("RestrictedApi"
  7.   protected void onCreate(@Nullable Bundle savedInstanceState) { 
  8.       super.onCreate(savedInstanceState); 
  9.       ReportFragment.injectIfNeededIn(this); 
  10.   } 
  11.    
  12.   // ... 

injectIfNeededIn是ReportFragment的静态方法

  1. public static void injectIfNeededIn(Activity activity) { 
  2.        // ProcessLifecycleOwner should always correctly work and some activities may not extend 
  3.        // FragmentActivity from support lib, so we use framework fragments for activities 
  4.        android.app.FragmentManager manager = activity.getFragmentManager(); 
  5.        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) { 
  6.            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit(); 
  7.            // Hopefully, we are the first to make a transaction
  8.            manager.executePendingTransactions(); 
  9.        } 
  10.    } 

低版本Activity兼容Lifecycle

SupportActivity是伴随Lifecycle才出现的,android.arch.lifecycle:extensions为早期还没有继承SupportActivity的Activity也提供了支持,通过LifecycleDispatcher实现ReportFragment的注入:

  1. class LifecycleDispatcher { 
  2.  
  3.     static void init(Context context) { 
  4.         if (sInitialized.getAndSet(true)) { 
  5.             return
  6.         } 
  7.         ((Application) context.getApplicationContext()) 
  8.                 .registerActivityLifecycleCallbacks(new DispatcherActivityCallback()); 
  9.     } 
  10.  
  11.     static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks { 
  12.         private final FragmentCallback mFragmentCallback; 
  13.  
  14.         DispatcherActivityCallback() { 
  15.             mFragmentCallback = new FragmentCallback(); 
  16.         } 
  17.  
  18.         @Override 
  19.         public void onActivityCreated(Activity activity, Bundle savedInstanceState) { 
  20.             if (activity instanceof FragmentActivity) { 
  21.                 ((FragmentActivity) activity).getSupportFragmentManager() 
  22.                         .registerFragmentLifecycleCallbacks(mFragmentCallback, true); 
  23.             } 
  24.             ReportFragment.injectIfNeededIn(activity); 
  25.         } 
  26.  
  27.     } 

之前还疑惑为什么ReportFragment的实现不写到SupportActivity中去,看到这里终于理解了其存在的意义了吧。

LifecycleDispatcher并不需要在Application中调用,他通过ContentProvider实现初始化

  1. public class ProcessLifecycleOwnerInitializer extends ContentProvider { 
  2.     @Override 
  3.     public boolean onCreate() { 
  4.         LifecycleDispatcher.init(getContext()); 
  5.         ProcessLifecycleOwner.init(getContext()); 
  6.         return true
  7.     }     

在android.arch.lifecycle:extensionsaar的AndroidManifest中注册:

  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
  2.     package="android.arch.lifecycle.extensions" > 
  3.  
  4.     <uses-sdk android:minSdkVersion="14" /> 
  5.  
  6.     <application> 
  7.         <provider 
  8.             android:name="android.arch.lifecycle.ProcessLifecycleOwnerInitializer" 
  9.             android:authorities="${applicationId}.lifecycle-trojan" 
  10.             android:exported="false" 
  11.             android:multiprocess="true" /> 
  12.     </application> 
  13.  
  14. </manifest> 

${applicationId}占位符,避免authroities冲突。

可见在无侵这件事情上做到了极致,这种无侵的初始化方法非常值得我们借鉴和使用。

两种Fragment

通过上面分析,我们知道Activity是通过ReportFragment代理了LifecycleOwner的实现。那么在Activity中添加的LifecycleOwner与Activity的Fragment的生命周期是否一致呢?答案是否定的

Android中存在两种Fragment有两种:

  • ADK自带的android.app.Fragment
  • Support包中的android.support.v4.app.Fragment(AndroidX也归为此类)

由于前者已经被@Deprecated,所以现在普遍使用的是后者,也就是Support或者AndroidX的Fragment。而出于低版本兼容性的考虑,ReportFragment是前者。

Activity对于两种Fragment生命周期回调的实际并不相同,以onResume和onStart为例,Activity回调的实际如下表:

上面表格中()中的数字表示依次执行的顺序,所以你会发现,adk fragment的onStart晚于support fragment,而onResume却更早执行

  • Activity的LifecycleOwner虽然是基于Fragment实现的,但是同一个Activity的LifecycleOwner与Fragment的生命周期回调实际并不一致。

这在我们的开发重要特备注意,不要视图让Fragment和LifecycleOwner的生命周期中的处理产生时序上的依赖关系。

总结

通过源码分析Activity对于LifecycleOwner的实现后,我们得到以下结论

  • Activity不直接调用HandleLifecycleEvent进行生命周期的分发,而是通过ReportFragment实现
  • ReportFragment的注入和过程全程无侵,值得我们借鉴和学习
  • 同一个Activity,其LifecycleOwner与Fragment的生命周期回调实际并不一致,需要特别注意
【责任编辑:未丽燕 TEL:(010)68476606】

点赞 0
版权声明:本文来源51CTO,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:http://developer.51cto.com/art/202102/644984.htm
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-17 01:00:26
  • 阅读 ( 1511 )
  • 分类:面试题

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢