-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
源码中的单例模式 #30
Comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
在 Android 系统中,我们经常会通过 Context 获取系统级别的服务,如 WindowsManagerService、ActivityManagerService 等,更常用的是一个 LayoutInflater 的类,这些服务会在合适的时候以单例的形式注册在系统中,在我们需要的时候就通过 Context 的 getSystemService(String name) 获取。
我们以 LayoutInflater 为例来说明,平时我们使用 LayoutInflater 较为常见的地方是在 RecyclerView 的 onCreateViewHolder 方法中:
通常我们使用 LayoutInflater.from(Context context) 来获取 LayoutInflater 服务,下面看看源码实现:
可以看到 from(Context context) 函数内部调用的是 Context 类的 getSystemService(String name) 方法,我们跟踪到 Context 类看到,该类是抽象类:
onCreateViewHolder 中使用的 Context 对象的具体实现类是什么呢?其实在 Application、Activity、Service 中都会存在一个 Context 对象,即 Context 的总个数为 Activity 个数 + Service 个数 + 1。而 RecyclerView 通常都是显示在 Activity 中,那么我们就以 Activity 中的 Context 来分析。
我们知道,一个 Activity 的入口是 ActivityThread 的 main 函数,在 main 函数中创建一个新的 ActivityThread 对象,并且启动消息循环(UI线程),创建新的 Activity、新的 Context 对象,然后将该 Context 对象传递给 Activity。下面看看 ActivityThread 源代码:
在 main 方法中,创建一个 ActivityThread 对象后,调用了其 attach 函数,并且参数为 false。在 attach 函数中,参数为 false 的情况下(即非系统应用),会通过 Binder 机制与 ActivityManager Service 通信,并且最终调用 handleLaunchActivity 函数,我们看看该函数的实现:
通过上面的代码分析可以知道,Context 的实现类为 ComtextImpl。我们继续跟踪 ContextImpl 类:
从 ContextImpl 类的部分代码中可以看到,在虚拟机第一次加载该类时会注册各种 ServiceFetcher,其中就包含了 LayoutInflater Service。将这些服务以键值对的形式存储在一个 Map 中,用户使用时只需要根据 key 来获取到对应的 ServiceFetcher,然后通过 ServiceFetcher 对象的 getService 函数来获取具体的服务对象。当第一次获取时,会调用 ServiceFetcher 的 createService 函数创建服务对象,然后将该对象缓存到一个列表中,下次再取时直接从缓存中获取,避免重复创建对象,从而达到单例的效果。
The text was updated successfully, but these errors were encountered: