无限 while 循环,而 AsyncTask 未完成

infinite while loop, while AsyncTask is not finish

我有一个 SplashScreen Activity,它调用 Asynctask Class 在 Internet 上获取信息。

我想等待我的 Asynctask 未完成(互联网速度连接期间的时间)

我的activity:

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

我的异步任务:

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

        SplashScreenActivity.test = false;

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

    }

从逻辑上讲,布尔值在 onPostExecute 中变为假,因此 while 循环停止并且意图必须开始但 while 循环永远不会停止...

这看起来像是隐藏在另一个问题中的问题,但要解决第一级问题,您可以尝试使用 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);
}

尝试使用非常简单的库: https://github.com/Arasthel/AsyncJobLibrary

开始你的 Splash activity:

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

在 Splash 的 "onCreate" 方法中 activity 做,你需要在后台和任务完成后,在主线程上做(更新列表):

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):

dependencies {
    ...
    implementation 'com.arasthel:asyncjob-library:1.0.3'
    ...
}

让我们使用简单的 interface 逻辑以安全的方式做您想做的事:

所以我们添加了简单的 interface 并重新定义了 MyAsnycTask class 的 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 它。所以我们实施它。在实现的方法中,我们使用 Intent:

转到下一个 Activity
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);

    }

当我们修改 MyAsnycTask class 的 constructor 时,我们必须像这样初始化它:

MyAsnycTask process = new MyAsnycTask(this);
process.execute();