获取LayoutInflater的三种方式分析

对于LayoutInflater的定义,我们来看一下官方文档,
Instantiates a layout XML file into its corresponding android.view.View objects.
意思是,将一个XML文件实例化为对应的View对象。

在实际开发中,我们避免不了需要使用到LayoutInflater类中的inflate()方法。对于LayoutInflater对象的获取,有三种方式。

LayoutInflater inflater = 
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);// 第一种方式

LayoutInflater inflater = LayoutInflater.from(context);// 第二种方式

LayoutInflater inflater = activity.getLayoutInflater();// 第三种方式
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

那么这三种方式有什么区别呢?

(1).第一种方式
getSystemService()是Android很重要的一个API,它是Context类的一个方法,根据传入的name来取得对应的Object,然后转换成相应的服务对象。Context.LAYOUT_INFLATER_SERVICE表示我们取得的是实例化layout的服务对象。

(2).第二种方式
我们来看一下它的内部实现。

/**
 * Obtains the LayoutInflater from the given context.
 */
public static LayoutInflater from(Context context) {
    LayoutInflater LayoutInflater =
    (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (LayoutInflater == null) {
        throw new AssertionError("LayoutInflater not found.");
    }
    return LayoutInflater;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

from()是LayoutInflater中的一个静态方法,返回LayoutInflater对象。我们可以看到,方法内部其实使用的是context.getSystemService(),也就是上述第一种方式。

(3).第三种方式
getLayoutInflater()是Activity类的一个方法,也就是说只有通过Activity类的引用才能调用,相比于第一种和第二种方式,此种方式存在一定的使用局限。我们来看一下它的内部实现。

Activity类的关键代码

package android.app;

public class Activity extends ContextThemeWrapper implements ... {
    ......
    private Window mWindow;
    ......

    @NonNull
    public LayoutInflater getLayoutInflater() {
        return getWindow().getLayoutInflater();
    }

    public Window getWindow() {
        return mWindow;
    }

    final void attach(...) {
        ......
        mWindow = new PhoneWindow(this);
        ......
    }

    ......
    ......
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

从源码可以看到,当我们调用getLayoutInflater()方法时,方法内部先调用了getWindow()方法,而getWindow()返回的是Activity类的mWindow成员变量,mWindow是Window类的引用。当Activity被创建时,会调用attach()方法,在attach()方法里面完成mWindow成员变量赋值,mWindow实际上是PhoneWindow类的对象。Window是一个抽象类,其内部的getLayoutInflater()方法是abstract的,PhoneWindow类继承自Window类,实现了getLayoutInflater()方法,即我们最终调用的是PhoneWindow类的getLayoutInflater()方法。

Window类的关键代码

package android.view;

public abstract class Window {

    ......

    @NonNull
    public abstract LayoutInflater getLayoutInflater();

    ......

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

PhoneWindow类的源码SDK并未给我们提供,从Android源码中我们可以找到PhoneWindow类的实现,路径\platform_frameworks_base-master\core\java\com\android\internal\policy\PhoneWindow.java。

PhoneWindow类的关键代码

package com.android.internal.policy;

public class PhoneWindow extends Window implements MenuBuilder.Callback {

    ......

    private LayoutInflater mLayoutInflater;

    ......

    public PhoneWindow(Context context) {
        super(context);
        mLayoutInflater = LayoutInflater.from(context);
    }

    @Override
    public LayoutInflater getLayoutInflater() {
        return mLayoutInflater;
    }

    ......
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

到这里,真相大白了。PhoneWindow类的getLayoutInflater()方法,内部使用的其实是LayoutInflater.from(context),即上述第二种方式。

**结论:
获取LayoutInflater对象,最终都是通过调用Context类的getSystemService()方法来实现的。**

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值