理解 Context.getSystemService 原理

本人只是Android小菜一个,写技术文章只是为了总结自己最近学习到的知识,从来不敢为人师,如果里面有不正确的地方请大家尽情指出,谢谢!本文基于原生 Android 9.0 源码来解析 Context.getSystemService 原理:frameworks/base/core/java/android/app/Activity.javaframeworks/base/core/j...
摘要由CSDN通过智能技术生成

本人只是Android小菜一个,写技术文章只是为了总结自己最近学习到的知识,从来不敢为人师,如果里面有不正确的地方请大家尽情指出,谢谢!

本文基于原生 Android 9.0 源码来解析 Context.getSystemService 原理:

frameworks/base/core/java/android/app/Activity.java
frameworks/base/core/java/android/view/ContextThemeWrapper.java
frameworks/base/core/java/android/view/LayoutInflater.java
frameworks/base/core/java/android/content/Context.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/SystemServiceRegistry.java
复制代码

1. 概述

Android系统为程序开发者提供了各种各样的系统服务,以满足在不同场景下的需求,例如:

  • LayoutInflater:把layout布局文件渲染成view控件对象;
  • DownloadManager:发起下载任务,从特定文件来源中下载文件;
  • CameraManager:调用系统摄像组件进行拍照录像等功能。

这里只列举了几个常用的系统服务,实际上现在Android框架中存在的系统服务要远远多于这些,基本涵盖了所有的系统服务类型,同时Android框架为了帮助程序开发者更便捷地获取和使用这些服务,提供了一个统一的接口Context.getSystemService(),通过这个接口,开发者可以很方便快捷地获取想要的系统服务。

通过获取LayoutInflater系统服务实例的过程来简单了解下getSystemService()的基本使用方法,示例代码如下:

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 1. 通过 getSystemService 系统接口获取 LayoutInflater 服务实例
        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        // 2. 使用获取到的 LayoutInflater 服务来把布局文件渲染成控件对象
        View view = inflater.inflate(R.layout.view_merge, null);
    }
}
复制代码

简直太简单了! 只通过一行代码就获取到了LayoutInflater实例,然后就可以“肆意”使用这个服务来完成自己想要的功能了。

知道这些就够了吗?当然不是,作为一个“有理想有抱负”的程序员,在知道一项技术的基本用法之后,接下来要做的就是了解其背后的原理和实现方式,争取做到“知其然更知其所以然”。

本文将通过分析系统服务类LayoutInflater实例的具体获取过程来讲解Context.getSystemService()的实现原理,虽然其本身的逻辑并不复杂,仍希望能对感兴趣但没有时间查看源码的同学有所帮助。

2. 理解 Context.getSystemService 原理

Android系统框架中提供的系统服务多种多样,要学习和理解其实现原理,必须要以一个具体的系统服务为切入点,在这里选择LayoutInflater服务为入口,通过对其实例获取过程的逐步分析来揭开Context.getSystemService()的神秘面纱。

2.1 LayoutInflater 获取过程

前面已经给出获取LayoutInflater服务实例的示例代码,如下:

// 在 Activity 中调用 getSystemService 获取 LayoutInflater 服务对象。
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
复制代码

这里通过Activity.getSystemService()获取LayoutInflater服务实例,直接看这块代码:

public Object getSystemService(@ServiceName @NonNull String name) {
    // 检查 context 是否存在,只有在 Activity 调用了 onCreate 才存在。
    if (getBaseContext() == null) {
        throw new IllegalStateException(
                "System services not available to Activities before onCreate()");
    }

    // 针对 WINDOW_SERVICE 和 SEARCH_SERVICE 可用直接返回相关服务实例。
    if (WINDOW_SERVICE.equals(name)) {
        return mWindowManager;
    } else if (SEARCH_SERVICE.equals(name)) {
        ensureSearchManager();
        return mSearchManager;
    }
    // 返回其他类型的系统服务,LayoutInflater 会走到这里。
    return super.getSystemService(name);
}
复制代码

Activity中返回了WINDOW_SERVICESEARCH_SERVICE两种特殊类型的系统服务,其他类型的服务则继续调用super.getSystemService()获取,这里的super指的是ContextThemeWrapper,转到这里继续分析:

@Override
public Object getSystemService(String name) {
    // 在获取 LayoutInflater 实例时传入的名字就是 LAYOUT_INFLATER_SERVICE,此时会走到这里。
    if (LAYOUT_INFLATER_SERVICE.equals(name)) {
        if (mInflater == null) {
            mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
        }
        return mInflater;
    }
    // 其他类型的系统服务继续调用 getSystemService 来获取服务实例。
    return getBaseContext().getSystemService(name);
}
复制代码

ContextThemeWrapper.getSystemService也没有真正返回服务实例,而是继续调用LayoutInflater.from():

/**
 * Obtains the LayoutInflater from the given context.
 */
public static LayoutInflater from(Context context) {
    // 调用 Context.getSystemService 获取 LayoutInflater 实例。
    LayoutInflater LayoutInflater =
            (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    // 获取失败则抛出异常。
    if (LayoutInflater == null) 
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值