同事在进行code review的时候问到我context中的getSystemService方法在哪实现的,他看到了一个ClipBoardManager来进行剪切板存储数据的工具方法中用到了context.getSystemService(),而此处我使用的是Application级别的Context进行调用的,可IDE跳转时发现当前类中的getSystemService()方法居然是抽象的,Context类就是一个抽象类,没有具体的实现,可在进行调用的时候却一切正常,同事好奇该方法具体实现在哪实现的,于是我俩一起看源码和查资料后发现有几个值得注意的地方:
- 系统service获取和分享的问题,源码中提示到:
Note: System services obtained via this API may be closely associated with the Context in which they are obtained from. In general, do not share the service objects between various different contexts (Activities, Applications, Services, Providers, etc.)
大意: 获取的系统service可能和他们的context有紧密联系,一般来说不要在不同的context之间分享服务对象,如Activity、Application、Service、Provider
明显同样的方法调用的具体实现不同,从同样拥有getSystemService的Activity的实现可以看到,虽然最终调用还是从LayoutInflater的context获取
/*
* Activity中的getSystemService()
*/
@Override
public Object getSystemService(@ServiceName @NonNull String name) {
if (getBaseContext() == null) {
throw new IllegalStateException(
"System services not available to Activities before onCreate()");
}
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
ensureSearchManager();
return mSearchManager;
}
// 以上的判断仅仅是为了检查是否为WindowManager获取窗口的服务
return super.getSystemService(name);
}
通过super.getSystemService(name)跳转到ContextThemeWrapper这个Context.java类的代理类中,然而也并非是真正的具体实现,但是在此我们可以得知LayoutInflater实际上也是获取的是Application级别的全局context,因为该context也是该类中的mBase获取的