【问题标题】:infinite while loop, while AsyncTask is not finish无限while循环,而AsyncTask没有完成
【发布时间】:2019-11-04 18:10:17
【问题描述】:

我有一个 SplashScreen Activity,它调用 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);

我的异步任务:

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

        SplashScreenActivity.test = false;

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

    }

逻辑上,onPostExecute 中的布尔值变为 false,因此 while 循环停止并且意图必须启动,但 while 循环永远不会停止...

【问题讨论】:

  • 嗯,test 设置为 true,所以你有 while(true) { }。你期待什么? :|
  • 也许时间过得太快了,试着在那里睡一会儿
  • 我尝试将SystemClock.sleep(1000); 放入while 循环,但@RicardoA 没有任何改变。
  • I want to wait while my Asynctask is not finish (time during on internet speed connection) 如果不是异步的,为什么还要异步执行?你这样做是错的。如果您真的想要这样做,请检查任务的状态。见developer.android.com/reference/android/os/…
  • @jmart SplashScreenActivity 是应用程序中第一个午餐的活动,它调用我的 asynctask,然后启动 MainActivity。我的问题代码在 SplashScreenActivity

标签: java android loops android-asynctask splash-screen


【解决方案1】:

让我们使用简单的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。所以我们实现它。在实现的方法中,我们使用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 类的 constructor 时,我们必须像这样初始化它:

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

【讨论】:

  • 这正是我需要的!谢谢
【解决方案2】:

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

【讨论】:

  • 请注意,这可能会在 AsyncTask 期间阻塞您的 UI 线程,从而很可能会出现“应用程序无响应”弹出窗口。您可能希望真正允许异步执行任务,并让onPostExecute() 通知活动它已准备好继续,而不是尝试使用布尔值或 CountDownLatch 进行阻塞。
【解决方案3】:

尝试使用非常简单的库: 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)                 
            }
        });
    }
});

连接库(app-project 目录下的build.gradle):

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    相关资源
    最近更新 更多