Drawable Xml资源文件解析过程

Drawable Xml资源文件解析过程

从drawable资源文件获取一个drawable对象,是通过调用Resources.getDrawable(int)方法实现。该方法主要流程如下:

// Resources.java
public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme)
            throws NotFoundException {
  ...
  return mResourcesImpl.loadDrawable(this, value, id, theme, true);
  ...
 }

// ResourcesImpl.java
@Nullable
    Drawable loadDrawable(Resources wrapper, TypedValue value, int id, Resources.Theme theme,boolean useCache) throws NotFoundException {
  ...
  // Cache相关
  Drawable dr;
  if (isColorDrawable) {
    dr = new ColorDrawable(value.data); // ColorDrawable
  } else {
    dr = loadDrawableForCookie(wrapper, value, id, null);
  }
...
}
private Drawable loadDrawableForCookie(Resources wrapper, TypedValue value, int id, Resources.Theme theme) {
  ...
  if (file.endsWith(".xml")) {
    // 创建XmlResourceParser
    Drawable.createFromXml(wrapper, rp, theme);
  } else {
    Drawable.createFromResourceStream(wrapper, value, is, file, null);
  }
  ...
}

最终进入Drawable类中

// Drawable.java
public static Drawable createFromXml(Resources r, XmlPullParser parser, Theme theme) throws XmlPullParserException, IOException {
...
  Drawable drawable = createFromXmlInner(r, parser, attrs, theme);
...
  return drawable
}

中间一系列的方法委托转发等调用后

// **.java
    @NonNull
    public Drawable inflateFromXml(@NonNull String name, @NonNull XmlPullParser parser,
            @NonNull AttributeSet attrs, @Nullable Theme theme)
            throws XmlPullParserException, IOException {
        // Inner classes must be referenced as Outer$Inner, but XML tag names
        // can't contain $, so the  tag allows developers to specify
        // the class in an attribute. We'll still run it through inflateFromTag
        // to stay consistent with how LayoutInflater works.
        if (name.equals("drawable")) {
            // 解析自定义drawable类型
            name = attrs.getAttributeValue(null, "class");
            if (name == null) {
                throw new InflateException(" tag must specify class attribute");
            }
        }
        // 通过根标签名创建对应Drawable实现类对象
        Drawable drawable = inflateFromTag(name);
        if (drawable == null) {
            // 是自定义的drawable,反射创建类实现
            drawable = inflateFromClass(name);
        }
        // xml子标签的解析交给具体drawable实现类处理
        drawable.inflate(mRes, parser, attrs, theme);
        return drawable;
    }

    private Drawable inflateFromTag(@NonNull String name) {
        switch (name) {
            case "selector":
                return new StateListDrawable();
            case "animated-selector":
                return new AnimatedStateListDrawable();
            case "level-list":
                return new LevelListDrawable();
            case "layer-list":
                return new LayerDrawable();
            case "transition":
                return new TransitionDrawable();
            case "ripple":
                return new RippleDrawable();
            case "color":
                return new ColorDrawable();
            case "shape":
                return new GradientDrawable();
            case "vector":
                return new VectorDrawable();
            case "animated-vector":
                return new AnimatedVectorDrawable();
            case "scale":
                return new ScaleDrawable();
            case "clip":
                return new ClipDrawable();
            case "rotate":
                return new RotateDrawable();
            case "animated-rotate":
                return new AnimatedRotateDrawable();
            case "animation-list":
                return new AnimationDrawable();
            case "inset":
                return new InsetDrawable();
            case "bitmap":
                return new BitmapDrawable();
            case "nine-patch":
                return new NinePatchDrawable();
            default:
                return null;
        }
    }

最后,对xml的解析通过drawable.inflate(mRes, parser, attrs, theme);交给了具体的drawable实现类来处理。

你可能感兴趣的:(Drawable Xml资源文件解析过程)