бесконечный цикл while, пока AsyncTask еще не закончен - PullRequest
2 голосов
/ 04 ноября 2019

У меня есть активность SplashScreen, которая вызывает класс Asynctask для получения информации в Интернете.

Я хочу подождать, пока моя Asynctask не закончится (время подключения к Интернету по скорости)

Моя активность:

public static boolean test = true;

[...]

final Liste en_ce_moment = new Liste("En ce moment au cinéma", nowMovie);
mesListes.add(en_ce_moment);

//call my Asynctask file 
fetchNowMovie process = new fetchNowMovie();
process.execute();

while(test)
{

}

Intent i = new Intent(SplashScreenActivity.this, MainActivity.class);
startActivity(i);

My Asynctask:

protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

        SplashScreenActivity.test = false;

        SplashScreenActivity.nowMovie.clear();
        SplashScreenActivity.nowMovie.addAll(list);

    }

Логически логическое значение стало ложным в onPostExecute, поэтому цикл while и намерение должны запускаться, но цикл while никогда не останавливается. ..

Ответы [ 3 ]

1 голос
/ 04 ноября 2019

Попробуйте использовать очень простую библиотеку: https://github.com/Arasthel/AsyncJobLibrary

Просто запустите свою активность Splash:

Intent i = new Intent(context, SplashScreenActivity.class);
startActivity(i);

В методе Splash "onCreate" выполните то, что вам нужно в фоновом режиме ипосле завершения миссии выполните в главном потоке (список обновлений):

AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {
    @Override
    public void doOnBackground() {

        //load from local DB or http-request:
        List<Movie> movieList = fetchNowMovie();
        //You can convert movieList to Json string, for example and save in SharedPreferences. Or you can use local DB for saving new movies.

        // Send the result to the UI thread and show it
        AsyncJob.doOnMainThread(new AsyncJob.OnMainThreadJob() {
            @Override
            public void doInUIThread() {
                Intent i = new Intent(splashScreenContext, MainActivity.class);
                startActivity(i);  
                //load movies from shared preferences or local Database in MainActivity (onCreate)                 
            }
        });
    }
});

Подключите библиотеку (build.gradle в каталоге app-project):

dependencies {
    ...
    implementation 'com.arasthel:asyncjob-library:1.0.3'
    ...
}
1 голос
/ 04 ноября 2019

Давайте сделаем то, что вы хотите сделать безопасным способом, используя простую логику interface:

Итак, мы добавили наш простой interface и мы переопределим ваш MyAsnycTask класс constructor какитак:

public class MyAsnycTask extends AsyncTask
{

    OnTaskFinished listener;

    // Our simple interface
    public interface OnTaskFinished {
        void TimeToNextActivity();
    }

    // Your MyAsnycTask class constructor
    public MyAsnycTask(OnTaskFinished l) {
        listener = l;
    }

    . . .

Как последняя строка кода в onPostExecute(), мы сделали все, что делаем. Так скажите это через наш listener:

listener.TimeToNextActivity();

Чтобы использовать наш interface, который мы добавили ранее, ваш Activity должен implements. Таким образом, мы реализуем это. И в реализованном методе мы переходим к следующему Activity с Intent:

public class MyActivity extends Activity
implements MyAsnycTask.OnTaskFinished
{

    @Override
    public void TimeToNextActivity()
    {
        // Here go to next activity
        Intent i = new Intent(this, MainActivity.class);
        startActivity(i);

    }

Когда мы изменили constructor нашего MyAsnycTask класса, мы должны инициализировать его следующим образом:

MyAsnycTask process = new MyAsnycTask(this);
process.execute();
1 голос
/ 04 ноября 2019

Это похоже на проблему, скрывающуюся внутри другой проблемы, но чтобы решить проблему первого уровня, вы можете попробовать использовать CountDownLatch вместо статического логического значения:

CountDownLatch latch = new CountDownLatch(1);
fetchNowMovie process = new fetchNowMovie(latch);
process.execute();

latch.await();

Intent i = new Intent(SplashScreenActivity.this, MainActivity.class);
startActivity(i);

Вам придется принятьзащелка как часть конструктора AsyncTask:

private final CountDownLatch latch;

public fetchNowMovie(CountDownLatch latch) {
    this.latch = latch;
}

// ...

protected void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);

    latch.countDown();

    SplashScreenActivity.nowMovie.clear();
    SplashScreenActivity.nowMovie.addAll(list);
}
...