switch caseステートメントエラー:case式は定数式でなければなりません


128

私のswitch-caseステートメントは昨日完全にうまくいきます。しかし、今朝の早い段階でコードを実行すると、eclipseはcase文に赤色で下線を引くエラーを表示し、次のように言います。case式は定数式である必要があります。以下が私のコードです:

public void onClick(View src)
    {
        switch(src.getId()) {
        case R.id.playbtn:
            checkwificonnection();
            break;

        case R.id.stopbtn:
            Log.d(TAG, "onClick: stopping srvice");
            Playbutton.setImageResource(R.drawable.playbtn1);
            Playbutton.setVisibility(0); //visible
            Stopbutton.setVisibility(4); //invisible
            stopService(new Intent(RakistaRadio.this,myservice.class));
            clearstatusbar();
            timer.cancel();
            Title.setText(" ");
            Artist.setText(" ");
            break;

        case R.id.btnmenu:
            openOptionsMenu();
            break;
        }
    }

すべてのR.id.intにはすべて赤の下線が引かれています。


R.id.playbtnなどの定義を教えてください。すべてが静的で最終的なものですか?
トーマス

2
おそらく、レイアウトを削除または変更したため、これらのIDはもう存在していないか、そのようなものです...
Vicente Plata

このクラスRは通常IDE / devツールによって生成されるため、通常は使用中のAndroidのバージョンに適しています。
cHao

私のR.id. *はすべて問題なく、android ..のgenクラスとメインレイアウトにも存在します。
HeartlessArchangel

回答:


274

通常のAndroidプロジェクトでは、リソースRクラスの定数は次のように宣言されます。

public static final int main=0x7f030004;

ただし、ADT 14以降、ライブラリプロジェクトでは、次のように宣言されます。

public static int main=0x7f030004;

つまり、定数はライブラリプロジェクトでは最終的なものではありません。したがって、コードはコンパイルできなくなります。

この解決策は簡単です。switchステートメントをif-elseステートメントに変換します。

public void onClick(View src)
{
    int id = src.getId();
    if (id == R.id.playbtn){
        checkwificonnection();
    } else if (id == R.id.stopbtn){
        Log.d(TAG, "onClick: stopping srvice");
        Playbutton.setImageResource(R.drawable.playbtn1);
        Playbutton.setVisibility(0); //visible
        Stopbutton.setVisibility(4); //invisible
        stopService(new Intent(RakistaRadio.this,myservice.class));
        clearstatusbar();
        timer.cancel();
        Title.setText(" ");
        Artist.setText(" ");
    } else if (id == R.id.btnmenu){
        openOptionsMenu();
    }
}

http://tools.android.com/tips/non-constant-fields

次のものを使用switchして、if-elseステートメントをステートメントにすばやく変換できます。

Eclipseで
にカーソルを移動しswitch、キーワードを押しCtrl+ 1[選択]

「switch」を「if-else」に変換します。

Android Studioで
カーソルをswitchキーワードに移動し、Alt+ を押してEnterから選択

「switch」を「if」に置き換えます。


私はそれだけで私は..私は新しいAndroidプロジェクトを作成し、スイッチ-case文と作業の罰金を使用迷ってしまった...他に-if文に私のスイッチ-case文を変更
HeartlessArchangel

1
最初のプロジェクトがライブラリプロジェクトを使用していて、新しいプロジェクトは使用していない可能性があります。
Benito Bertoli

申し訳ありませんが、本当にここでは初心者です。説明できますか
HeartlessArchangel

7
少なくともEclipseでは、スイッチをif / elseに自動的に変換できます。switchキーワードをクリックします。その後、ctrl-1
Darren Cato 2013

1
コンパイラーは、コンパイル時に式を認識する必要があります。finalキーワードがなければ、実行時に変数を変更できます。
Benito Bertoli

52

プロジェクトプロパティの「Is Library」のチェックを外すとうまくいきました。


2
プロジェクト名を右クリックします。次に、プロパティ-> Androidをクリックします。ポップアップの右下には、「ライブラリ」というラベルの付いたセクションがあります。その下で「ライブラリ」オプションがチェックされている場合、プロジェクトをライブラリプロジェクトにしたくない場合はチェックを外します。次に、クリーンして再構築します。ライブラリプロジェクトにしたい場合は、スイッチをif else if条件付きに変更する必要があります。
VikingGlen 2014年

5
ライブラリプロジェクトが「Is Library」とマークされている理由はいくつかあります。これは問題に対する適切な解決策ではありません。通常のアプリのように動作するライブラリを作成することにより、Androidプロジェクトの構造を壊します。
ADTC 2015年

13

解決策はこのようにして行うことができます:

  1. ただ、割り当てる整数を
  2. 作るの変数を最終

例:

public static final int cameraRequestCode = 999;

これがお役に立てば幸いです。


8

R.id。*。ADT 14は最終的な静的intとして宣言されていないため、スイッチケースコンストラクトでは使用できません。代わりにif else句を使用できます。


はい、tools.android.comでそれを読んだので、新しいプロジェクトを作成して上記のコードを使用しましたが、うまく機能します。
HeartlessArchangel

1
tools.android.com/recent/buildchangesinrevision14の「ライブラリプロジェクトの改訂」セクションを参照してください
Blackbelt

6
なぜ彼らがこの変更を行ったのかは意味がありません。
Andrew S

8

この問題の簡単な解決策は次のとおりです。

スイッチをクリックしてCTL + 1を押すと、スイッチがif-elseブロックステートメントに変更され、問題が解決します


7

if-elseの代わりに素敵なスイッチを維持するこの他のソリューションはどうですか?

private enum LayoutElement {
    NONE(-1),
    PLAY_BUTTON(R.id.playbtn),
    STOP_BUTTON(R.id.stopbtn),
    MENU_BUTTON(R.id.btnmenu);

    private static class _ {
        static SparseArray<LayoutElement> elements = new SparseArray<LayoutElement>();
    }

    LayoutElement(int id) {
        _.elements.put(id, this);
    }

    public static LayoutElement from(View view) {
        return _.elements.get(view.getId(), NONE);
    }

}

コードでこれを行うことができます:

public void onClick(View src) {
    switch(LayoutElement.from(src)) {
    case PLAY_BUTTTON:
        checkwificonnection();
        break;

    case STOP_BUTTON:
        Log.d(TAG, "onClick: stopping srvice");
        Playbutton.setImageResource(R.drawable.playbtn1);
        Playbutton.setVisibility(0); //visible
        Stopbutton.setVisibility(4); //invisible
        stopService(new Intent(RakistaRadio.this,myservice.class));
        clearstatusbar();
        timer.cancel();
        Title.setText(" ");
        Artist.setText(" ");
        break;

    case MENU_BUTTON:
        openOptionsMenu();
        break;
    }
}

列挙型は静的であるため、これによる影響は非常に限定的です。懸念される唯一のウィンドウは、関連する二重ルックアップです(最初に内部SparseArrayで、後でスイッチテーブルで)。

とは言っても、この列挙型は、必要に応じて、IDへの参照を維持することにより、流暢な方法でアイテムを取得するためにも利用できますが、それは別の話です。


列挙型は、メモリの膨張のため、Androidでは推奨されません。そして、それがAOSPで使用されない主な理由であり、intがどこでも見られる理由です。
ADTC 2015年


3

クラスで変数が宣言されている関数でスイッチを使用すると、このエラーが発生しました。

private void ShowCalendar(final Activity context, Point p, int type) 
{
    switch (type) {
        case type_cat:
            break;

        case type_region:
            break;

        case type_city:
            break;

        default:
            //sth
            break;
    }
}

finalクラスの開始時に変数を宣言すると、問題は解決しました。

final int type_cat=1, type_region=2, type_city=3;

1
enumintこの場合のより良い代替案です。メソッドの呼び出し元は、無効なタイプの関数を呼び出すことができません。
nhahtdh 2013

特定のint型があるので、intを使用しても問題ありません。しかし、私は列挙型の例を知りたいです:D
aimiliano

i have specific int types so its ok if i use ints本当に意味がありません。列挙型の例について:docs.oracle.com/javase/tutorial/java/javaOO/enum.html
nhahtdh

つまり、関数の入力int変数の型は常にこれらの3つの型のいずれかになるため、列挙型の例のおかげで何も壊れません:)
aimiliano

i mean that the incoming int variable type in the function will always be one of these 3 types so it won't break anythingこれはあなたの仮定です。他の誰かが任意の番号で関数を誤って呼び出す可能性があります。ではenum、仮定する必要はありません。言語によって強制されます。
nhahtdh 2013

2

それは、プロジェクトにライブラリを追加しようとしたときに同じ状況に遭遇したことです。突然、すべてのswitchステートメントがエラーを表示し始めました!

追加したライブラリを削除しようとしましたが、機能しませんでした。どのようにして「プロジェクトをクリーンアップしたとき」すべてのエラーが発生しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.