Skocz do zawartości
matej1410

AsyncTask -wywoływanie nowego wątku poprzez naciśniecie przycisku

    Rekomendowane odpowiedzi

    Witam.

    Czy można przy okazji korzystania z AsyncTaska sprawdzić czy wątek, który przed chwilką właśnie uruchomiłem, poprzez naciśniecie przycisku, jeszcze się wykonuje?

    Chciałbym to sprawdzać po to, żeby uchronić się przed tym, żeby nowy wątek nie powstał dopóki stary się nie zakończy.

    Przedstawiam kawałek kodu:

    package com.example.progressbarthreading;
    
    import android.os.AsyncTask;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ProgressBar;
    
    public class MainActivity extends AppCompatActivity {
    
        Button bt_startujWatek;
    
        ProgressBar progressBar;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            bt_startujWatek = findViewById(R.id.button);
    
            progressBar = findViewById(R.id.progressBar);
            progressBar.setProgress(100);
    
    
            bt_startujWatek.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
    
                    AsyncTask<String,String,String> watekAsynchroniczny = new AsyncTask<String, String, String>() {
                        @Override
                        protected void onPostExecute(String s) {
                            super.onPostExecute(s);
                            if(s.equals("done"))
                            {
                                Log.d("watek","skonczony");
                            }
                        }
                        @Override
                        protected String doInBackground(String... strings) {
                            int postep=100;
                            Log.d("watek","rozpoczety");
                            while(postep>0) {
                                try {
                                    Thread.sleep(50);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
    
                                postep=postep-1;
                                progressBar.setProgress(postep);
                            }
                            return "done";
                        }
                    };
                watekAsynchroniczny.execute();
                }
            });
    
    }
    }
    
    
    
    
    

    Teraz program działa tak, że tyle ile razy nacisnę przycisk bt_startujWatek tyle razy do jakby "kolejki wątków" dochodzą nowe i wykonują się jeden po drugim.

    dodana zawartość

    Chociaż można by zablokować działania przycisku i już nie doda się w ten sposób kolejnego wątku do kolejki

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    Napisano (edytowane)
    2 godziny temu, matej1410 napisał:

    Chociaż można by zablokować działania przycisku i już nie doda się w ten sposób kolejnego wątku do kolejki

    Istnieje ryzyko że ktoś zdąży kliknąć w przycisk na tyle szybko że ten drugi wątek się uruchomi przed blokadą ?

    Ogólnie wątki mogą istnieć jednocześnie. Chodzi o to żeby ich działanie było zsynchonizowane. Na przykład gdy zmieniają wartość jakiejś zmiennej nie powinny tego robić jednocześnie. 

    W Twoim przypadku zmiany na progressBar powinieneś przenieść do metody do której dostęp ma tylko jeden wątek jednocześnie. Osiągniesz to dodając słowo synchronized przed nazwą metody:

    //........
                        @Override
                        protected String doInBackground(String... strings) {
                           showProgress()
                        }
    
    //.......
     synchronized void showProgress() {
         int postep=100;
         Log.d("watek","rozpoczety");
         while(postep>0) {
             try {
                     Thread.sleep(50);
             } catch (InterruptedException e) {
                      e.printStackTrace();
             }
    
             postep=postep-1;
             progressBar.setProgress(postep);
         }
     
     }

     

    Edytowane przez Coders Lab

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    senega

    Po wciśnięciu przycisku musisz go wyłączyć. Jak zakończy się wątek przechwyć odpowiednie zdarzenie i włącz przycisk. W większości przypadków załatwi to sprawę.

    • Piwko! 1

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

    Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

    Zarejestruj nowe konto

    Załóż nowe konto. To bardzo proste!

    Zarejestruj się

    Zaloguj się

    Posiadasz już konto? Zaloguj się poniżej.

    Zaloguj się

    • Ostatnio przeglądający   0 użytkowników

      Brak zarejestrowanych użytkowników przeglądających tę stronę.

    x