关于Android的问号?和@符号的用法

来源:互联网 发布:vpn代理软件破解版 编辑:程序博客网 时间:2024/05/18 02:14

最近修改一个python写的小工具,用作移除Android项目中没用到的资源如string, color等等。在做的过程中,style和styleable一直困扰不清,后面查了一下stackoverflow http://stackoverflow.com/questions/4585808/difference-between-declare-styleable-and-style ,总结一下这个问题。


一、style的作用

首先需要了解style的作用是什么!Android developer http://developer.android.com/intl/zh-CN/guide/topics/ui/themes.html 给出了一个例子我觉得很说明问题。

如果我们需要定义很多个这样的TextView:

复制代码
<TextView    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:textColor="#00FF00"    android:typeface="monospace"    android:text="@string/hello" />
复制代码

为了便于修改,我们可以修改成这样:

<TextView    style="@style/CodeFont"    android:text="@string/hello" />
复制代码
<?xml version="1.0" encoding="utf-8"?><resources>    <style name="CodeFont" parent="@android:style/TextAppearance.Medium">        <item name="android:layout_width">fill_parent</item>        <item name="android:layout_height">wrap_content</item>        <item name="android:textColor">#00FF00</item>        <item name="android:typeface">monospace</item>    </style></resources>
复制代码

这样,我们只要采用CodeFont的style的view都会有一样的外观,而且很容易修改。所以,style可以理解成自定义外观,重复利用代码的作用。

至于styleable,我们注意到它是在attrs.xml中定义的,所以我们可以想象,它可能是用于定义attr在style里面用。具体的区别马上就讲。

二、declare-styleable 和 style 的区别

为什么在attrs.xml里面会有styleable的定义呢?

我们注意到上文中的CodeFont的定义,有没有发现item里面的name都是android开头?因为这些属性都是在android中预先设定好的,所以我们可以随意用。但是如果我们想用自己定义的属性名呢?这时候styleable的作用就出现了。我们只需要把attr的定义包围在styleable里面,这样定义的属性名就可以在style里面用。示例如下(示例来自上文给出的stackoverflow链接):

复制代码
<?xml version="1.0" encoding="utf-8"?><resources>   <attr name="attrib1" format="string" /> <declare-styleable name="blahblah">    <attr name="attrib2" format="string" /> </declare-styleable>
复制代码

 

在attrs.xml里面定义了两个attr,attrib1是普通的,attrib2包围在declare-styleable标签中;

<com.custom.ViewClass  attrib1="xyz" attrib2="abc"/>

 

我们可以在layout/someactivity.xml里直接使用这些attr;

<style name="customstyle" parent="@android:style/Widget.TextView">    <item name="attrib2">text value</item>    <!--  customize other, standard attributes too: -->    <item name="android:textColor">@color/white</item> </style>

 

在styles.xml中,我们就能用attrib2。(原网站这里写成了attrib1,怀疑是笔误。)

后来我验证过attrib1也能使用在style里面(我真的不确定,逻辑上应该不能才对,但是编译就是通过了。。。),那么这里就必须说明attr包不包含在styleable里面的另一个主要区别了,stackoverflow中是这么说的:

The constructor of the custom class needs to read the styled and the non-styled attributes in a different way: the styled attributes with obtainStyledAttributes(), and the non-styled attributes with attr.getAttributeValue() or similar.

 也就是说,获取两者的方式不一样。获取attrib1用attr.getAttributeValue(),而获取attrib2用obtainStyledAttributes()。也就是说,styleable属性的获取方式具体可以参见android developer http://developer.android.com/intl/zh-CN/training/custom-views/create-view.html 这里我截取一段代码加以说明它的一般流程:

复制代码
public PieChart(Context ctx, AttributeSet attrs) {   super(ctx, attrs);   //得到styleable的全部值,返回是一个TypedArray。注意R.styleable.PieChart   TypedArray a = context.getTheme().obtainStyledAttributes(        attrs,        R.styleable.PieChart,        0, 0);   try {       //得到styleable里面的属性值。R.styleable.PieChart_showText       mShowText = a.getBoolean(R.styleable.PieChart_showText, false);       mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);   } finally {       a.recycle();   }}
复制代码

 

为了保证a.recycle()被调用,把它用finally包起来。

三、怎么移除与declare-styleable相关attr无用资源

最后简单介绍一下我的工作,怎么移除这里面的无用资源呢?

注意到,decleare-styleable中定义的attr在R.java中出现在两个地方:1)在class attr 中又有对应的变量;2)在class styleable中也有对应的变量。举个例子(截取的项目里面的一小部分,有改动):

View Code

我们在分析哪些attr没用到的时候是这么做的:

  1. 解析R.java,将class attr和class styleable中的变量分别存在两个集合里面,比如UnusedAttrSet和UnusedStyleableSet;
  2. 解析src下的代码和res下的代码,得到两个集合UsedAttrSet和UsedStyleableSet;
  3. 将UsedSet合并。因为用到的attr的可能是在styleable里面定义的,所以attr用了表示styleable也用了;用到styleable的肯定表示attr对应的量也用到了。
  4. 最后分别打印出attr和styleable中没有用到的量。

这里有些同学可能会问,styleable集合肯定包含在attr里面吧?为什么还要找styleable呢?是的,可以直接判断attr有没有用到,这里我把它们独立主要是为了比如有个变量在attr和styleable中都没有用到,我就只需要去查找styleable就行了。这在调试代码的时候有用。


0 0
原创粉丝点击