1. 程式人生 > >android.content.res.Resources$NotFoundException: Resource ID #0x23ecb2

android.content.res.Resources$NotFoundException: Resource ID #0x23ecb2

在平時開發中肯定會遇到android.content.res.Resources$NotFoundException資源找不到的問題,最常見的就是setText()傳入了一個int型別的資料,遇到這種問題很好解決,把int型別資料換成string就行了,原因太簡單了不再解釋。但是在開發中我遇到了另外一種現象,我們一起來分析一下采坑之路。

一,需求

1,專案中有個需求是在執行某個環節的時候播放一個短音訊,類似於叮咚這種音訊。產品提供好mp3檔案,我把資原始檔放在了raw下。
2,編寫一個SoundPlayUtils工具類來播放短音訊,程式碼如下:

public class SoundPlayUtils {
    // SoundPool物件
    private static SoundPool mSoundPlayer = new SoundPool(10,
            AudioManager.STREAM_SYSTEM, 5);
    private static SoundPlayUtils soundPlayUtils;

/**
 * 初始化
 *
 * @param context
 */
public static SoundPlayUtils init(Context context) {
    if (soundPlayUtils == null) {
        synchronized (SoundPlayUtils.class) {
            if (soundPlayUtils == null) {
                soundPlayUtils = new SoundPlayUtils(context);
            }
        }
    }
    return soundPlayUtils;
}

public SoundPlayUtils(Context context) {
    //如果有其他聲音在此初始化
    mSoundPlayer.load(context, R.raw.one, 1);
    mSoundPlayer.load(context, R.raw.two, 1);
    mSoundPlayer.load(context, R.raw.three, 1);

}

/**
 * 播放聲音
 *
 * @param soundID
 */
public void play(int soundID) {
    Log.d("####","play voice:"+soundID);
    mSoundPlayer.play(soundID, 1, 1, 0, 0, 1);
}

3,在需要呼叫的時候就SoundPlayUtils.init(mApplication).play(1)

其實這個工具類不是特別優雅,會存在一些問題,具體可以看這篇分享 SoundPool

二,問題

我們可以看出需求很簡單,但是使用者反饋了一個問題,我們跟蹤後發現是在呼叫SoundPlayUtils.init(mApplication).play(1)後出現了android.content.res.Resources$NotFoundException。後來檢查了程式碼,沒有發現任何問題,raw資源下明明有相關資源,百思不得其解。

三,分析

綜合以上進行分析

1,是不是在apk安裝的時候檔案損壞,或者安裝出現異常導致的。後來使用者說重啟就可以了,如果是資原始檔損壞重啟也無法解決,除非重新安裝apk。
2,會不會在我 mSoundPlayer.load的時候載入失敗導致的,於是我把load相關的程式碼全都註釋了,執行程式也沒有問題。
3,我們知道在這行程式碼mSoundPlayer.load(context, R.raw.one, 1)其中R.raw.one它對應的是int型別的資料,在安卓中所有的資源都會對映對應一個id,這也是我們通常所說的R檔案,那麼會不會是映射出了問題。
4,另外我們用的是安卓4.4版本,這個問題是偶現,概率比較低。因此可以斷定資源對映時出現了沒有對應關係的資源。

四,解決

任何問題只要程式閃退了,肯定是大問題,出現這個問題如果沒有異常捕獲程式肯定閃退。因此即使找不到具體原因我們起碼不能讓程式閃退,所以目前解決辦法在load的時候進行異常捕獲。當然不是所有問題都能找到具體根源,希望有大牛詳細的解釋這個問題。

   public SoundPlayUtils(Context context) {
            //如果有其他聲音在此初始化
     try {
            mSoundPlayer.load(context, R.raw.one, 1);
            mSoundPlayer.load(context, R.raw.two, 1);
            mSoundPlayer.load(context, R.raw.three, 1);
      } catch (Resources.NotFoundException e) {
        e.printStackTrace();
    }