Android使用TypedArray获取资源getResourceId方法下标越界异常问题

Android中重复资源获取方式TypedArray

在Android中会经常遇到使用重复的资源,比如显示用户等级;往往用户等级的icon基本都是一个尺寸只是显示的内容不一样而已。而显示的时候需要通过获取接口数据中用户等级来决定如果显示。如果按住以往的逻辑我们可能会通过if—else或者swich—case等方式来显示。(太麻烦)Android在很早的时候为我们提供了TypedArray的方式获取类似的资源。

res文件夹的array.xml中创建资源数组

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="small_grade_level_img_array">
        <item>@drawable/small_level_1</item>
        <item>@drawable/small_level_2</item>
        <item>@drawable/small_level_3</item>
        <item>@drawable/small_level_4</item>
        <item>@drawable/small_level_5</item>
        <item>@drawable/small_level_6</item>
        <item>@drawable/small_level_7</item>
        <item>@drawable/small_level_8</item>
        <item>@drawable/small_level_9</item>
        <item>@drawable/small_level_10</item>
        <item>@drawable/small_level_11</item>
        <item>@drawable/small_level_12</item>
        <item>@drawable/small_level_13</item>
        <item>@drawable/small_level_14</item>
        <item>@drawable/small_level_15</item>
    </string-array>
</resources>

可是使用“”string-array”标签创建一个字符串Array资源,里面的每一个“item”都代表一个元素而元素的默认角标从0开始到length-1。
如果想要使用刚刚创建的资源就需要声明TypedArray对象了。

Context.getResources().obtainTypedArray(R.array.small_grade_level_img_array)

通过obtainTypedArray方法就可以获得一个TypedArray对象。如果想要使用TypedArray对象中的某一个资源一般会使用getResourceId()方法。该方法如下图:getResourceId—API描述
从上图可以了解到getResourceId方法中有两个参数。第一个代表资源的索引。比如我们在xml中的资源有15个索引就是从0~14。不过也可以传递其他的只系统会匹配是否有对应的资源如果没有就需要使用第二个参数默认资源。也就是通过索引找不到对应的资源就会返回默认资源。默认资源就是xml中item标签里面的值。

需要注意TypedArray容易出现的问题

往往我们使用TypedArray中都会在Activity或者Adapter中初始化它。也就是Activity或者Adapter持有一个TypedArray对象。但是在一些复杂的情况中可能我们经常要刷新某一个控件或者item布局。而在刷新完之后我们并没有释放TypedArray就调用getResourceId方法。如果可以将索引控制在资源索引的范围内是没有问题的,但是一旦超出了资源的索引范围就会出现数组下标越界的错误。
资源下标越界
如果避免该问题,TypedArray中提供了一个recycle()方法该方法可以将资源释放。我们再试使用这个资源的时候会重新生成一个TypedArray对象。就不会出现越界的问题了。源代码如下:

/**
     * Recycles the TypedArray, to be re-used by a later caller. After calling
     * this function you must not ever touch the typed array again.
     *
     * @throws RuntimeException if the TypedArray has already been recycled.
     */
    public void recycle() {
        if (mRecycled) {
            throw new RuntimeException(toString() + " recycled twice!");
        }

        mRecycled = true;

        // These may have been set by the client.
        mXml = null;
        mTheme = null;
        mAssets = null;

        mResources.mTypedArrayPool.release(this);
    }

官方文档如下:TypedArray的getResoucedId方法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊猫vs笨笨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值