3

minSDK 8 と targetSDK 11 用にビルドしています。

<uses-sdk android:minSdkVersion="8"
          android:targetSdkVersion="11"/>

私はlogcatでこれを取得します:

WARN/dalvikvm(2114): VFY:  rejected Lcom/examplecompany/project/TidalStreams/Data/gTidalStreamsHourlyHW;.<clinit> ()V

WARN/dalvikvm(2114): Verifier rejected class Lcom/digitaliridium/tides/TidalStreams/Data/gTidalStreamsHourlyHW;

他のいくつかのデバイスの中でも、2 つの欲望があります。1 つは 2.2.2 を実行しており、もう 1 つは 2.3.3 を実行しています。

2.2.2 では、次のjava.lang.VerifyError行を取得します。

public void onCreate(){
    ...

    gTidalStreamsHourlyHW.init();

    ...
}

その方法がこちらinit()。これはごく普通のクラスの唯一のメソッドです。

public static void init(){


    int insertPosition;
    System.arraycopy(gTidalStreamHourlyHW1, 0,  gTidalStreamHourlyHW, 0, gTidalStreamHourlyHW1.length);

    insertPosition = gTidalStreamHourlyHW1.length;
    System.arraycopy(gTidalStreamsHourlyHW2.gTidalStreamHourlyHW1, 0,  gTidalStreamHourlyHW, insertPosition, gTidalStreamsHourlyHW2.gTidalStreamHourlyHW1.length);

    insertPosition += gTidalStreamsHourlyHW2.gTidalStreamHourlyHW1.length;
    System.arraycopy(gTidalStreamsHourlyHW3.gTidalStreamHourlyHW1, 0,  gTidalStreamHourlyHW, insertPosition, gTidalStreamsHourlyHW3.gTidalStreamHourlyHW1.length);

    ...

gTidalStreamsHourlyHW約 350k の大規模なデータ配列です。Java の 64k コンパイル単位制限を回避するために、複数のファイルに分割する必要がありました。

このinitメソッドは単に System.arraycopy() を使用して、これらの複数の静的配列を 1 つに連結します。

minSDK レベルを 7 に下げてみましたが、問題は同じです。

2.2.2 を実行しているエミュレータでも失敗します。

4

1 に答える 1

3

私は Android の大ファンですが、時には弁護のしようがありません :(

エラーが静的初期化子に関係していることを示す手掛かりがエラーに含まれています。それは次の<clinit>「メソッド」名です。

WARN/dalvikvm(2114): VFY:  rejected Lcom/examplecompany/project/TidalStreams/Data/gTidalStreamsHourlyHW;.<clinit> ()V

これは、エラーがstatic { ... }初期化ブロック、またはstaticクラス メンバーの初期化に関係している可能性があることを示しています。

私のクラスには静的配列初期化子があります:

 public static shcTidalStreamPointStruct[] gTidalStreamHourlyHW1  = new shcTidalStreamPointStruct[]{

            new shcTidalStreamPointStruct("000A",48.766667,-10.066667,51.116667,1.316667,"89",95,0.8,0.4,125,0.9,0.4,172,0.7,0.4,216,0.7,0.4,242,0.8,0.4,261,0.9,0.4,281,0.7,0.4,305,0.7,0.4,339,0.6,0.3,14,0.6,0.3,58,0.6,0.3,71,0.7,0.3,91,0.7,0.4,"GB",0),
            new shcTidalStreamPointStruct("000B",49.533333,-9.983333,51.116667,1.316667,"89",122,0.6,0.3,166,0.8,0.4,192,0.9,0.4,213,0.9,0.5,239,0.9,0.5,255,0.9,0.5,286,0.9,0.4,330,0.7,0.4,9,0.9,0.4,38,1,0.5,52,1.1,0.5,68,0.9,0.5,104,0.6,0.3,"GB",0),
            new shcTidalStreamPointStruct("000C",48.898333,-9.163333,51.116667,1.316667,"89",102,0.4,0.2,118,0.6,0.3,172,0.7,0.4,197,0.7,0.4,212,0.7,0.4,250,0.7,0.4,283,0.5,0.3,321,0.3,0.2,337,0.5,0.3,13,0.7,0.4,33,0.7,0.4,54,0.5,0.3,98,0.4,0.2,"GB",0),

283個の要素があります。

このコードのみでテスト プロジェクトをビルドし、2.2 以下で失敗することを確認しました。2.3以降では動作します。

問題はイニシャライザの行数です! 197 行が残るまで、一度に 1 行ずつ取り出しました。

そのため、Java の 64k コンパイル ユニットの制限と同様に、Android クラス ローダーには、静的初期化の行数/サイズに関連する文書化されていない制限 (またはバグ) があります。

修正は、ファイルをさらに分割して行数を減らすことでした。ふぐぐぐり……

于 2013-03-31T17:45:43.083 に答える