switch statement case error: ekspresi kasus harus berupa ekspresi konstan


128

Pernyataan kasus sakelar saya berfungsi dengan baik kemarin. Tetapi ketika saya menjalankan kode tadi pagi gerhana memberi saya kesalahan menggarisbawahi pernyataan kasus dalam warna merah dan mengatakan: ekspresi kasus harus ekspresi konstan, itu konstan saya tidak tahu apa yang terjadi. Ini kode saya di bawah ini:

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;
        }
    }

Semua R.id.int semuanya digarisbawahi dalam warna merah.


Bisakah Anda memberikan definisi R.id.playbtndll? Apakah semuanya statis dan final?
Thomas

2
Mungkin Anda menghapus / memodifikasi tata letak Anda dan id itu tidak ada lagi atau sesuatu seperti itu ...
Vicente Plata

Kelas Rini biasanya dihasilkan oleh alat IDE / dev, jadi biasanya benar untuk versi Android yang digunakan.
cao

R.id saya * semua baik-baik saja dan ada di kelas gen android .. dan juga dalam tata letak utama.
HeartlessArchangel

Jawaban:


274

Dalam proyek Android biasa, konstanta dalam kelas R sumber daya dinyatakan seperti ini:

public static final int main=0x7f030004;

Namun, pada 14 ADT, dalam proyek perpustakaan, mereka akan dinyatakan seperti ini:

public static int main=0x7f030004;

Dengan kata lain, konstanta tidak final dalam proyek perpustakaan. Karenanya kode Anda tidak lagi dapat dikompilasi.

Solusi untuk ini sederhana: Ubah pernyataan switch menjadi pernyataan 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

Anda dapat dengan cepat mengonversi switchpernyataan menjadi if-elsepernyataan menggunakan yang berikut ini:

Di Eclipse
Pindahkan kursor Anda ke switchkata kunci dan tekan Ctrl+ 1lalu pilih

Konversikan 'alihkan' ke 'jika-lain'.

Di Android Studio,
Pindahkan kursor Anda ke switchkata kunci dan tekan Alt+ Enterlalu pilih

Ganti 'switch' dengan 'if'.


saya mengubah pernyataan switch-case saya menjadi statement if-if .. Itu hanya membuat saya bertanya-tanya saya membuat proyek android baru dan menggunakan pernyataan switch-case dan bekerja dengan baik ..
HeartlessArchangel

1
Bisa jadi proyek pertama Anda menggunakan proyek perpustakaan dan proyek baru Anda tidak.
Benito Bertoli

saya tidak mengerti bahwa maaf saya benar-benar seorang pemula di sini .. dapatkah Anda jelaskan
HeartlessArchangel

7
Setidaknya gerhana akan memungkinkan Anda mengonversi sakelar ke if / else secara otomatis. klik pada kata kunci sakelar. lalu tekan ctrl-1
Darren Cato

1
Kompiler perlu ekspresi untuk diketahui pada waktu kompilasi. Tanpa finalkata kunci, variabel dapat diubah saat runtime.
Benito Bertoli

52

Hapus centang "Apakah Perpustakaan" dalam proyek Properties bekerja untuk saya.


2
Klik kanan pada nama proyek Anda. Kemudian klik pada properties -> Android. Di bagian kanan bawah popup adalah bagian bertuliskan "Perpustakaan". Di bawahnya, jika opsi "is Library" dicentang, hapus centang jika Anda tidak ingin proyek Anda menjadi proyek perpustakaan. Kemudian bersihkan dan bangun kembali. Jika Anda ingin itu menjadi proyek perpustakaan, maka Anda harus mengubah peralihan Anda ke kondisional if if seperti yang dinyatakan di tempat lain.
VikingGlen

5
Ada alasan mengapa proyek perpustakaan ditandai dengan "Apakah Perpustakaan". Ini bukan solusi yang tepat untuk masalah - ini akan merusak struktur proyek Android Anda dengan membuat apa yang seharusnya menjadi perpustakaan untuk berperilaku seperti aplikasi biasa.
ADTC

13

Solusi bisa dilakukan dengan cara ini:

  1. Hanya menetapkan satu nilai untuk Integer
  2. Buat variabel ke final

Contoh:

public static final int cameraRequestCode = 999;

Semoga ini bisa membantu Anda.


8

R.id. *, karena ADT 14 tidak lebih dideklarasikan sebagai final static int sehingga Anda tidak dapat menggunakan konstruksinya. Anda bisa menggunakan klausa lain jika bukan.


ya saya telah membaca itu di tools.android.com, saya juga mencoba membuat proyek baru dan menggunakan kode di atas dan berfungsi dengan baik .. bagaimana itu?
HeartlessArchangel

1
tools.android.com/recent/buildchangesinrevision14 lihat bagian "Library Project Revamp"
Blackbelt

6
Mengapa mereka melakukan perubahan ini tidak masuk akal.
Andrew S

8

Solusi sederhana untuk masalah ini adalah:

Klik pada saklar dan kemudian tekan CTL + 1, Ini akan mengubah saklar Anda ke pernyataan blok if-else, dan akan menyelesaikan masalah Anda


7

Bagaimana dengan solusi lain ini untuk mempertahankan sakelar yang bagus alih-alih jika ada:

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);
    }

}

Jadi dalam kode Anda, Anda dapat melakukan ini:

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;
    }
}

Enum bersifat statis sehingga ini akan memiliki dampak yang sangat terbatas. Satu-satunya jendela yang perlu diperhatikan adalah pencarian ganda yang terlibat (pertama pada SparseArray internal dan kemudian pada tabel switch)

Yang mengatakan, enum ini juga dapat digunakan untuk mengambil item dengan lancar, jika diperlukan dengan menjaga referensi ke id ... tapi itu cerita untuk waktu lain.


Enum tidak disarankan di Android karena memori mereka menggembung; dan itulah alasan utama mengapa mereka tidak pernah digunakan dalam AOSP - dan alasan mengapa Anda melihat int di mana-mana.
ADTC


3

Itu membuat saya kesalahan ini ketika saya menggunakan sakelar di fungsi dengan variabel yang dideklarasikan di kelas saya:

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;
    }
}

Masalahnya terpecahkan ketika saya mendeklarasikan finalke variabel di awal kelas:

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

1
enumadalah alternatif yang lebih baik intdalam hal ini. Penelepon metode tidak akan dapat memanggil fungsi dengan tipe yang tidak valid.
nhahtdh

saya punya tipe int tertentu jadi ok jika saya menggunakan ints. Namun saya ingin tahu contoh dengan enum: D
aimiliano

i have specific int types so its ok if i use intsTidak masuk akal. Mengenai contoh enum: docs.oracle.com/javase/tutorial/java/javaOO/enum.html
nhahtdh

i mean bahwa tipe variabel int yang masuk dalam fungsi akan selalu menjadi salah satu dari 3 jenis ini sehingga tidak akan merusak apa pun terima kasih untuk contoh enum :)
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 anythingIni asumsi Anda . Orang lain dapat salah memanggil fungsi dengan nomor arbitrer. Dengan enum, Anda tidak perlu berasumsi, itu dipaksakan oleh bahasa.
nhahtdh

2

Saya ingin menyebutkan bahwa, saya menemukan situasi yang sama ketika saya mencoba menambahkan perpustakaan ke proyek saya. Tiba-tiba semua pernyataan beralih mulai menunjukkan kesalahan!

Sekarang saya mencoba untuk menghapus perpustakaan yang saya tambahkan, bahkan kemudian tidak berfungsi. bagaimana " ketika saya membersihkan proyek " semua kesalahan baru saja meledak!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.