うさがにっき

読書感想文とプログラムのこと書いてきます

Volleyライブラリ内でNegativeArraySizeException

概要

Volleyライブラリを使うとごく稀にNegativeArraySizeExceptionが発生する
エラー原因はわからないがアプリが落ちないために対策した方法

詳細

Volleyライブラリを使ってキャッシュを使っていると以下のエラーがごく稀におこる

java.lang.NegativeArraySizeException: -618
    at com.android.volley.toolbox.DiskBasedCache.streamToBytes(DiskBasedCache.java:316)
    at com.android.volley.toolbox.DiskBasedCache.get(DiskBasedCache.java:117)
    at com.android.volley.CacheDispatcher.run(CacheDispatcher.java:100)

このエラーはvolley内でcatchされておらず、発生した場合アプリが強制終了してしまう

NegativeArraySizeExceptionは配列のindexにマイナスを指定したときにおこる例外
例)int[] a = new int[-1];

volley内でこれが発生しているのは以下の箇所
DiskBasedCache.java

    private static byte[] streamToBytes(InputStream in, int length) throws IOException {
        // ここの配列作成で発生
        byte[] bytes = new byte[length];
        int count;
        int pos = 0;
        while (pos < length && ((count = in.read(bytes, pos, length - pos)) != -1)) {
            pos += count;
        }
        if (pos != length) {
            throw new IOException("Expected " + length + " bytes, read " + pos + " bytes");
        }
        return bytes;
    }

なので、このメソッドでNegativeArraySizeExceptionを投げるように宣言し、予備足し元でIOExceptionと発生にIOExceptionと同じような処理をするように修正した

    private static byte[] streamToBytes(InputStream in, int length) throws IOException, NegativeArraySizeException {
        // ここの配列作成で発生
        byte[] bytes = new byte[length];
        int count;
        int pos = 0;
        while (pos < length && ((count = in.read(bytes, pos, length - pos)) != -1)) {
            pos += count;
        }
        if (pos != length) {
            throw new IOException("Expected " + length + " bytes, read " + pos + " bytes");
        }
        return bytes;
    }

そもそも何故発生したのかがわからないのが非常に気持ち悪いが、これで一応落ちなくはなるはず