Android LayoutInflater源码分析及使用(一)
2016-03-18 10:32
459 查看
说到LayoutInflater可能大家首先想到的是加载layout,一般我们会习惯性的调用View中的这个静态方法
上面说到我们在Context中发现他是一个抽象类,那么我们就去它的子类中查找,在ContextWrapper中我们终于找到了,
我们继续找它的下一个子类Activity,找到了,可是并没有我们要找的LayoutInflater
在之前我们讲过Activity的attach方法是在ActivityThreaad的performLaunchActivity方法中传进来的,
然后我们在找我们需要的LayoutInflater,就是两条杠之间的,我们找到PolicyManager类,然后找到相应的方法
public static View inflate(Context context, int resource, ViewGroup root) { LayoutInflater factory = LayoutInflater.from(context); return factory.inflate(resource, root); }或者直接得到LayoutInflater对象,然后调用它的下面方法
public View inflate(int resource, ViewGroup root, boolean attachToRoot) { if (DEBUG) System.out.println("INFLATING from resource: " + resource); XmlResourceParser parser = getContext().getResources().getLayout(resource); try { return inflate(parser, root, attachToRoot); } finally { parser.close(); } }可是LayoutInflater是个抽象方法,我们是不能直接初始化的,一般都是这样来得到这个对象的
LayoutInflater LayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);我们通过查看源码,发现上面的方法在Context中也是也抽象方法,并没有真正的实现
public abstract Object getSystemService(String name);今天我们就来一步步分析怎么得到LayoutInflater这个对象的,至于他的inflate方法我们也是经常遇到的,这篇我们先跳过,下一篇在作详解,
上面说到我们在Context中发现他是一个抽象类,那么我们就去它的子类中查找,在ContextWrapper中我们终于找到了,
@Override public Object getSystemService(String name) { return mBase.getSystemService(name); }那么我们在看看mBase是什么,可能很失望,它就是传进来的Context
protected void attachBaseContext(Context base) { if (mBase != null) { throw new IllegalStateException("Base context already set"); } mBase = base; }我们继续跟踪,找到ContextWrapper的一个子类ContextThemeWrapper,发现getSystemService方法正好有我们要找的LayoutInflater,可是却没什么用,因为它需要实例化之后才能克隆,
@Override public Object getSystemService(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from(mBase).cloneInContext(this); } return mInflater; } return mBase.getSystemService(name); }
我们继续找它的下一个子类Activity,找到了,可是并没有我们要找的LayoutInflater
@Override public Object getSystemService(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; } return super.getSystemService(name); }饶了一大圈白费力气结果还是没找到。不要气馁,回到刚才我们说的ContextWrapper类中的getSystemService方法,我们来看一下mBase是怎么传进来的,最终我们在Activity的这个方法找到了它
final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config) { attachBaseContext(context); ………………………… }
在之前我们讲过Activity的attach方法是在ActivityThreaad的performLaunchActivity方法中传进来的,
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ………………………… Context appContext = createBaseContextForActivity(r, activity); ………………………… activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config); ………………………… return activity; }也就是说ContextWrapper中的mBase其实就是在这里传进来的,我们继续查看createBaseContextForActivity方法
private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) { ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token); …………………… return baseContext; }看到了吧,其实Context的真正实现类是ContextImpl
/** * Common implementation of Context API, which provides the base * context object for Activity and other application components. */ class ContextImpl extends Context {找到它就好办了,我们来查找一下getSystemService方法
@Override public Object getSystemService(String name) { ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name); return fetcher == null ? null : fetcher.getService(this); }看到没,其实SYSTEM_SERVICE_MAP就是个HashMap,那它究竟是怎么保存进去的,我们继续查看,发现有一个方法叫registerService,在这里面保存的
private static void registerService(String serviceName, ServiceFetcher fetcher) { if (!(fetcher instanceof StaticServiceFetcher)) { fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++; } SYSTEM_SERVICE_MAP.put(serviceName, fetcher); }我们还发现了有一个静态代码块,存进去的比较多,我们随便找几个我们平时比较常见的看看
static { ………………………… registerService(ACTIVITY_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler()); }}); registerService(ALARM_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(ALARM_SERVICE); IAlarmManager service = IAlarmManager.Stub.asInterface(b); return new AlarmManager(service, ctx); }}); registerService(AUDIO_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return new AudioManager(ctx); }}); ………………………… registerService(INPUT_SERVICE, new StaticServiceFetcher() { public Object createStaticService() { return InputManager.getInstance(); }}); registerService(DISPLAY_SERVICE, new ServiceFetcher() { @Override public Object createService(ContextImpl ctx) { return new DisplayManager(ctx.getOuterContext()); }}); registerService(INPUT_METHOD_SERVICE, new StaticServiceFetcher() { public Object createStaticService() { return InputMethodManager.getInstance(); }}); ……………………………… ……………………………… registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext()); }}); ……………………………… ……………………………… // Note: this was previously cached in a static variable, but // constructed using mMainThread.getHandler(), so converting // it to be a regular Context-cached service... registerService(POWER_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(POWER_SERVICE); IPowerManager service = IPowerManager.Stub.asInterface(b); return new PowerManager(ctx.getOuterContext(), service, ctx.mMainThread.getHandler()); }}); registerService(SEARCH_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return new SearchManager(ctx.getOuterContext(), ctx.mMainThread.getHandler()); }}); ………………………… registerService(TELEPHONY_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return new TelephonyManager(ctx.getOuterContext()); }}); ………………………… registerService(VIBRATOR_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return new SystemVibrator(ctx); }}); registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER); registerService(WIFI_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(WIFI_SERVICE); IWifiManager service = IWifiManager.Stub.asInterface(b); return new WifiManager(ctx.getOuterContext(), service); }}); registerService(WIFI_P2P_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE); IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b); return new WifiP2pManager(service); }}); ………………………… registerService(CAMERA_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return new CameraManager(ctx); } }); ………………………… }
然后我们在找我们需要的LayoutInflater,就是两条杠之间的,我们找到PolicyManager类,然后找到相应的方法
public static LayoutInflater makeNewLayoutInflater(Context context) { return sPolicy.makeNewLayoutInflater(context); }sPolicy其实就是Policy,我们来查看一下它的源码,找到相应的方法
public LayoutInflater makeNewLayoutInflater(Context context) { return new PhoneLayoutInflater(context); }看这里我们终于明白了,其实我们通过getSystemService得到的LayoutInflater 就是PhoneLayoutInflater,其实他继承的是LayoutInflater,我们可以看一下
public class PhoneLayoutInflater extends LayoutInflater {好了,到此为止LayoutInflater LayoutInflater =(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);这个方法我们已经分析完了,其实他得到的就是PhoneLayoutInflater这个类,有时间我们在来分析一下它的inflate方法,也是我们最常用到的一个方法。
相关文章推荐
- 在Android应用中读取彩信文件
- Android ListView获取当前可视区域条目数据
- Android 布局文件XML编写注意项
- android线程
- android在代码中修改view的布局
- JNI回调数据给android
- android view构造函数研究
- android 动态更新sql
- 自定义BaseActivity
- android 多线程下载 断点续传
- Android客户端与服务端交互的三种方式
- android图片处理之ImageView的ScaleType
- android如何实现ListView中的CheckBox的全选、反选、全不选
- Android 手势识别类 ( 二 ) GestureDetector 源码浅析
- Android 以jar包方式共享资源注意事项
- android Matrix的pre、post、set三种变形方式
- Android 手势识别类 ( 一 ) GestureDetector 基本介绍
- Android——Bundle savedInstanceState的作用
- androidListView分页加载总是回到头部的问题
- android Listview,gridview局部刷新,部分刷新