Czy jest jakaś pętla, w której można powtórzyć if-a?

0

Witam ! Mam pytanie, czy jest jakaś pętla w której można powtórzyć if-a ? Chodzi mi o to że gdy po sprawdzeniu warunku, będzie on sprzeczny i wykona się nie to co jest w ciele if-tylko to co jest w ciele else i aby w tym else było coś takiego co każe programowi ponownie wykonać tego całego if-a.

Wiem że strasznie to zagmatfałem ale mam nadzieje że zrozumiecie :-)

if(backgroundSeracher.getStatus() == AsyncTask.Status.FINISHED)
        {
            Toast.makeText(this, "OK", Toast.LENGTH_LONG).show();
        }
        else
        {
            Toast.makeText(this, "NO OK", Toast.LENGTH_LONG).show();
        }
0

Nie no, tak to się z tobą nikt nie dogada.

czy jest jakaś pętla w której można powtórzyć if-a ?

Niby gdzie jest ta pętla w tym kodzie.

0

Chodzi mi o to jakiej pętli mam tam użyć ?

0

jakiejkolwiek, na każdej można zrobić wszystko

0

Niby programiści a nie potrafią zrozumieć z kontekstu że OP chce mieć coś na wzór pętli do-while lub while.

0
While loop napisał(a):

Niby programiści a nie potrafią zrozumieć z kontekstu że OP chce mieć coś na wzór pętli do-while lub while.

O to chodzi, tylko pętla while wykonuje się jeśli warunek ma wartość true, a mój ma false na początku

0

!true == false

0

Rekurencja ?

1

Na javie się nie znam, ale można uzyć while

while (true) {
	if(backgroundSeracher.getStatus() == AsyncTask.Status.FINISHED)
			{
				Toast.makeText(this, "OK", Toast.LENGTH_LONG).show();
				break;
			}
			else
			{
				Toast.makeText(this, "NO OK", Toast.LENGTH_LONG).show();
			}
}

ale nie potrzebujesz do tego if-a:

while (backgroundSeracher.getStatus() != AsyncTask.Status.FINISHED) {
	Toast.makeText(this, "NO OK", Toast.LENGTH_LONG).show();
}
Toast.makeText(this, "OK", Toast.LENGTH_LONG).show();
0

Moja rada, na razie daruj sobie androida i naucz się podstaw.
Możesz zacząć od http://hackerrank.com/ https://www.spoj.com/ albo https://main.edu.pl/pl

0
DEEEP 1029 napisał(a):

Chodzi mi o to że gdy po sprawdzeniu warunku, będzie on sprzeczny i wykona się nie to co jest w ciele if-tylko to co jest w ciele else i aby w tym else było coś takiego co każe programowi ponownie wykonać tego całego if-a.

Odpowiem, abstrahując od Javy. Zmienne w1, w2 itd. będą u mnie zmiennymi (binarnymi), która "odpowiadają za kolejne warunki". Zmienna z będzie czasem zmienną pomocniczą przy bardziej złożonych warunkach.

Przepraszam, jeśli to wszystko, co przeczytasz, już wiesz. :)


Mniej-więcej można powiedzieć, że opisane przez ciebie zachowanie to główne zastosowanie instrukcji continue – w różnych językach. Przykład (pseudokod):

while (w1 == true) { // lub też po prostu while(w1) – ale nie w każdym języku to działa identycznie! Np. w Javascripcie działa chyba inaczej niż w Javie
    if (w2 == true) {
        zrobCos();
    } else {
        continue; // przeskocz na początek pętli
    }
}

Jednak ogólnie pętla while działa na takiej zasadzie, że powyższy kod może być równie dobrze zapisany w ten sposób:

while (w1 == true) {
    if (w2 == true) {
        zrobCos();
    } // a jeżeli warunek nie jest spełniony, przeskocz na początek pętli
}

Obie powyższe pętle zrobią to samo.


Jeżeli masz tylko jeden warunek – i nie wiesz, czy dać go w argumencie pętli (w nawiasach), czy też w ifie – to najprawdopodobniej nie potrzeba do tego ifa (jak wspomniał @Panczo). Przykład (pseudokod):

while (w1 == true) {
   zrobCos();
}

Powyższa pętla wykona się tak długo, jak długo warunek będzie spełniany. Instrukcja continue jest wykonywana jakby niejawnie (piszę "jakby", bo nie chcę wchodzić w szczegóły jakiegoś języka).


Jeżeli Twój warunek byłby na początku false – a chciałbyś, żeby stał się true po którymś obiegu pętli – możesz go zanegować w argumencie pętli. Przykład (pseudokod):

z = zrobCosPoczatkowego();
w1 = (z == cosTam); // przypisuję zmiennej w1 wartość true lub false, w zależności od funkcji zrobCosPoczatkowego()
while (!w1) { // dopóki !false, czyli true. Można też while(w1 == false)
    z = zrobCos();
    w1 = (z == cosTam);
}

Ta pętla mogłaby zostać wykorzystana na przykład do generowania liczb pseudolosowych z zadanego przedziału; w uproszczeniu: while (!(granicaDolna < liczba < granicaGorna)) { liczba = losuj(); }.

W powyższym kodzie mamy dwa wystąpienia tej samej (!) linijki. To nie całkiem dobrze. Należy unikać takich powtórzeń, o czym mówi szeroko stosowana zasada DRY (Don't Repeat Yourself). Wydaje mi się, że to mógł być jeden z głównych powodów wprowadzenia instrukcji do-while (w niektórych językach). Tak więc powyższe możemy zapisać prościej (a nawet jeśli tak samo prosto, to na pewno krócej):

z = zrobCosPoczatkowego();
do {
    z = zrobCos();
    w1 = (z == cosTam); // przypisuję zmiennej w1 wartość true lub false, w zależności od funkcji zrobCosPoczatkowego()
} while (!w1);

Lub jeszcze krócej:

do {
    z = zrobCos();
} while (!(z == cosTam));

UPDATE: Nie wspomniałem o instrukcji goto, ale może już nie będą gmatwał.

1

Moje trzy grosze: trochę inny kontekst: wydaje mi się że OP chciałby skorzystać z pętli żeby np. zrobić retry na nieudanym zadaniu które było wykonane asynchronicznie.

0

Spróbowałem zrobić to:

while (true) {
    if(backgroundSeracher.getStatus() == AsyncTask.Status.FINISHED)
            {
                System.out.println("OK");
                break;
            }
            else
            {
                 System.out.println("NO OK");
            }
}

Aplikacja po prostu się zacięła.
Specjalnie w onPostExecute dodałem na końcu

Toast.makeText(context, "Zakończono", Toast.LENGTH_LONG).show();

I to mi się wyświetla, a jest to ostanie polecenie i po nim status powinien zmienić się na FINISHED, a w Logcat-ie dalej wyświetla się NO OK

0

Spróbuj dodać na końcu pętli while

Thread.sleep (100)
0

Dodałem, aplikacja dalej się blokuje i cały czas jest NO OK :-/

0
DEEEP 1029 napisał(a):

Spróbowałem zrobić to:

while (true) {
    if(backgroundSeracher.getStatus() == AsyncTask.Status.FINISHED)
            {
                System.out.println("OK");
                break;
            }
            else
            {
                 System.out.println("NO OK");
            }
}

Aplikacja po prostu się zacięła.
Specjalnie w onPostExecute dodałem na końcu

Toast.makeText(context, "Zakończono", Toast.LENGTH_LONG).show();

I to mi się wyświetla, a jest to ostanie polecenie i po nim status powinien zmienić się na FINISHED, a w Logcat-ie dalej wyświetla się NO OK

Pokaż cały kod asynctasku, pomożemy. Na pierwszy rzut oka wartość w backgroundSeracher.getStatus() nie jest zmieniana. PS to raczej powinien być backgroundSearcher a nie Seracher.

0

Cały AsyncTask: https://pastebin.com/FrV9txj6

0

Pytanie do kodu z pierwszego wpisu:

if(backgroundSeracher.getStatus() == AsyncTask.Status.FINISHED)
        {
            Toast.makeText(this, "OK", Toast.LENGTH_LONG).show();
        }
        else
        {
            Toast.makeText(this, "NO OK", Toast.LENGTH_LONG).show();
        }

Czy tutaj wyświetlane jest OK albo NO OK?

0

To za co się zabierasz nie jest takie proste: moja rada, na początku zapoznaj się z biblioteką Retrofit + Gson - taki zestaw znacznie ułatwi implementację.

0

A jak zamienisz Thread.sleep na SystemClock.sleep(1000)?

0

Dalej jest NO OK

0

@DEEEP 1029: a czy nie można by odwrócić zależności – pętla w jakiejś metodzie asynchronicznej?

0

W takim razie spróbujmy użyć semaforów. Dodaj sobie pole semafor do BackgroundSerachera (możesz przekazać go w konstruktorze). Semafor inicjalizujesz z wartością 0 poza obiektem BackgroundSerachera i go tam przekazujesz. Teraz ważne: przed każdym returnem w metodzie doInBackground dajesz na obiekcie semafora - semafor.release(). A później

twojSeracher.execute(cośtam)
semafor.acquire()

https://developer.android.com/reference/java/util/concurrent/Semaphore

1 użytkowników online, w tym zalogowanych: 0, gości: 1