switch case deyim hatası: case ifadeleri sabit ifade olmalıdır


129

Anahtar durum ifadem dün mükemmel çalışıyor. Ancak bu sabah erken saatlerde kodu çalıştırdığımda tutulması bana kırmızı renkli vaka ifadelerinin altını çizen bir hata verdi ve şöyle diyor: vaka ifadeleri sabit ifade olmalı, sabittir, ne olduğunu bilmiyorum. İşte benim kodum:

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

Tüm R.id.intlerinin altı kırmızıyla çizilmiştir.


Vs.'nin tanımını verebilir misiniz R.id.playbtn? Her şey durağan ve nihai mi?
Thomas

2
Muhtemelen düzeninizi sildiniz / değiştirdiniz ve bu kimlikler artık mevcut değil ya da onun gibi bir şey ...
Vicente Plata

Sınıf Rgenellikle IDE / dev araçları tarafından oluşturulur, bu nedenle genellikle kullanılan Android sürümü için doğrudur.
cHao

Benim R.id. * bilgilerim iyi ve android'in gen sınıfında var .. ve ayrıca ana düzende.
HeartlessArchangel

Yanıtlar:


274

Normal bir Android projesinde, kaynak R sınıfındaki sabitler şu şekilde bildirilir:

public static final int main=0x7f030004;

Ancak ADT 14 itibariyle bir kütüphane projesinde şu şekilde ilan edilecekler:

public static int main=0x7f030004;

Diğer bir deyişle, sabitler bir kütüphane projesinde nihai değildir. Bu nedenle kodunuz artık derlenmeyecektir.

Bunun çözümü basittir: switch ifadesini if-else ifadesine dönüştürün.

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

Aşağıdakileri kullanarak bir switchifadeyi hızlı bir şekilde ifadeye dönüştürebilirsiniz if-else:

Eclipse'de
İmlecinizi switchanahtar sözcüğe getirin ve Ctrl+ tuşuna basın ve 1ardından seçin

'Switch'i' if-else 'olarak dönüştürün.

Android Studio'da
İmlecinizi switchanahtar kelimeye getirin ve Alt+ tuşuna basın ve Enterardından

'Switch'i' if 'ile değiştirin.


durum değiştirme ifademi else-if ifadesiyle değiştirdim .. Yeni bir android projesi oluşturduğumu ve durum değiştirme ifadesini kullandım ve iyi çalıştığımı merak ettim ..
HeartlessArchangel

1
İlk projeniz bir kütüphane projesi kullanıyor ve yeni projeniz kullanmıyor olabilir.
Benito Bertoli

anlamıyorum, üzgünüm burada gerçekten acemiyim .. açıklayabilir misin
HeartlessArchangel

7
Eclipse, en azından otomatik olarak anahtarı if / else'e dönüştürmenize izin verecektir. anahtar kelimeyi tıklayın. sonra ctrl-1'e basın
Darren Cato

1
Derleyicinin ifadenin derleme sırasında bilinmesi gerekir. finalAnahtar kelime olmadan, çalışma zamanında bir değişken değiştirilebilir.
Benito Bertoli

52

Proje Özelliklerindeki "Kitaplık" seçeneğinin işaretini kaldırmak benim için çalıştı.


2
Proje adınıza sağ tıklayın. Ardından özelliklere tıklayın -> Android. Açılır pencerenin sağ alt tarafında "Kitaplık" etiketli bir bölüm vardır. Altında, "Kitaplıktır" seçeneği işaretliyse, projenizin bir kitaplık projesi olmasını istemiyorsanız işaretini kaldırın. Ardından temizleyin ve yeniden oluşturun. Bir kütüphane projesi olmasını istiyorsanız, başka bir yerde belirtildiği gibi, anahtarınızı başka bir koşullu olarak değiştirmeniz gerekir.
VikingGlen

5
Bir kütüphane projesinin "Kitaplıktır" ile işaretlenmesinin nedenleri vardır. Bu, soruna uygun bir çözüm değildir - kitaplıkların olması gerekenleri normal uygulamalar gibi davranmasını sağlayarak Android proje yapınızı bozacaktır.
ADTC

13

Çözüm şu şekilde yapılabilir:

  1. Sadece atamak değeri için Tamsayı
  2. Make değişkeni için son

Misal:

public static final int cameraRequestCode = 999;

Umarım bu sana yardımcı olur.


8

R.id. *, ADT 14 artık nihai statik int olarak bildirilmediğinden, anahtar durumu yapısında kullanamazsınız. Bunun yerine if else cümlesini kullanabilirsiniz.


evet bunu tools.android.com'da okudum, ayrıca yeni bir proje oluşturmaya çalıştım ve yukarıdaki kodu kullandım ve gayet iyi çalışıyor .. bu nasıl?
HeartlessArchangel

1
tools.android.com/recent/buildchangesinrevision14 "Library Project Revamp" bölümüne bakın
Blackbelt

6
Bu değişikliği neden yaptılar hiç mantıklı değil.
Andrew S

8

Bu problem için basit çözüm:

Tıklayın anahtarı ve ardından basın CTL + 1, O if-else blok açıklamaya Switch'inizi değişecek ve sorununuzu çözecektir


7

If-else yerine güzel anahtarını korumak için bu diğer çözüme ne dersiniz?

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

}

Yani kodunuzda bunu yapabilirsiniz:

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

Numaralandırmalar statik olduğundan, bunun etkisi çok sınırlıdır. Endişe edilecek tek pencere, ilgili çift arama olacaktır (önce dahili SparseArray'de ve daha sonra anahtar tablosunda)

Bununla birlikte, bu enum aynı zamanda öğeleri akıcı bir şekilde almak için de kullanılabilir, gerekirse id'ye bir atıfta bulunarak ... ama bu başka bir zaman için bir hikaye.


Numaralandırmalar, bellek şişkinliği nedeniyle Android'de önerilmez; AOSP'de hiç kullanılmamalarının ana nedeni de budur - ve her yerde ints görmenizin nedeni budur.
ADTC


3

Sınıfımda açıklanan değişkenlerle bir işlevde switch'i kullandığımda bana şu hatayı atıyordu:

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

finalSınıfın başlangıcındaki değişkenlere bildirdiğimde sorun çözüldü :

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

1
enumintbu durumda daha iyi bir alternatiftir . Yöntemin çağırıcısı, geçersiz türdeki işlevi çağıramaz.
nhahtdh

belirli int türlerim var, bu yüzden ints kullanırsam sorun yok. Ancak enum ile bir örnek bilmek istiyorum: D
aimiliano

i have specific int types so its ok if i use intsGerçekten mantıklı değil. Enum örneği ile ilgili olarak: docs.oracle.com/javase/tutorial/java/javaOO/enum.html
nhahtdh

Demek istediğim, işlevdeki gelen int değişken türü her zaman bu 3 türden biri olacak, bu yüzden enum örneği için teşekkürler hiçbir şeyi
bozmayacak

i mean that the incoming int variable type in the function will always be one of these 3 types so it won't break anythingBu senin varsayımın. Bir başkası işlevi rastgele numara ile yanlış arayabilir. İle enum, bunun dil tarafından uygulandığını varsaymanıza gerek yok.
nhahtdh

2

Şunu belirtmek isterim ki, projeme kütüphane eklemeye çalıştığımda da aynı durumla karşılaştım. Birdenbire tüm anahtar ifadeleri hatalar göstermeye başladı!

Şimdi eklediğim kütüphaneyi kaldırmaya çalıştım, o zaman bile işe yaramadı. nasılsa " projeyi temizlediğimde " tüm hatalar bitti!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.