Android 当使用ExecutorService的WaitTermination方法时,如何显示进度条?

Android 当使用ExecutorService的WaitTermination方法时,如何显示进度条?,android,concurrency,executorservice,android-progressbar,Android,Concurrency,Executorservice,Android Progressbar,我正在构建一个应用程序,它可以从几个网页中获取价格,然后在所有任务完成后显示结果。一切正常,除了我正在努力添加进度条 下面是我试图做的一个简化版本。按下一个按钮后,程序运行两个任务:第一个睡眠3秒,第二个睡眠1-7秒。完成所有任务后,将显示每个任务的演讲信息 公共类MainActivity扩展了AppCompatActivity{ Button button; ProgressBar progressBar; @Override protected void onCreate(Bundle s

我正在构建一个应用程序,它可以从几个网页中获取价格,然后在所有任务完成后显示结果。一切正常,除了我正在努力添加进度条

下面是我试图做的一个简化版本。按下一个按钮后,程序运行两个任务:第一个睡眠3秒,第二个睡眠1-7秒。完成所有任务后,将显示每个任务的演讲信息

公共类MainActivity扩展了AppCompatActivity{

Button button;
ProgressBar progressBar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button = findViewById(R.id.btn);
    progressBar = findViewById(R.id.pb);

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            progressBar.setVisibility(View.VISIBLE);

            ExecutorService executorService = Executors.newFixedThreadPool(5);

            executorService.submit(new Task1());
            executorService.submit(new Task2());

            executorService.shutdown();

            try {
                executorService.awaitTermination(1, TimeUnit.MINUTES);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            progressBar.setVisibility(View.INVISIBLE);

        }
    });



}

private class Task1 implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep(3000);
            Log.d("task1", "run: ");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, "task1", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

private class Task2 implements Runnable {

    @Override
    public void run() {
        try {
            Log.d("task2", "run: ");
            Thread.sleep(7000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, "task2", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
}

据我所知,问题是在使用终止方法时,所有线程都被阻塞,包括UI线程,因此任务结果只有在所有任务完成后才会出现

是否有一种方法可以等待所有任务完成,同时仍显示进度条?

是的,关于等待终止,您是对的。但它只阻塞了主线程,其他线程则不受其影响

解决问题的一种方法是定义活动任务计数器。每次运行任务时,它都会增加。每次任务结束时,包括失败计数器都会减少

当然,您应该删除该终止方法。在Android中,以及大多数与UI相关的框架中,您不应该阻止UI线程

我的命题的伪代码:

Button button;
ProgressBar progressBar;
int activeTaskCounter = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button = findViewById(R.id.btn);
    progressBar = findViewById(R.id.pb);

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ExecutorService executorService = Executors.newFixedThreadPool(5);

            executorService.submit(new Task1());
            executorService.submit(new Task2());
            executorService.shutdown();
        }
    });
}

private void increaseActiveCounter() {
    activeTaskCounter += 1;
    progressBar.setVisibility(View.VISIBLE);
}

private void decreaseActiveCounter() {
    activeTaskCounter -= 1;
    if (activeTaskCounter == 0) {
        progressBar.setVisibility(View.INVISIBLE);
    }
}

private class Task1 implements Runnable {
    @Override
    public void run() {
        // It's lambda here, but you can use anonymous class. It's up to you
        runOnUiThread(() -> increaseCounter());
        try {
            Thread.sleep(3000);
            Log.d("task1", "run: ");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            runOnUiThread(() -> decreaseActiveCounter());
        }
       
    }
}

private class Task2 implements Runnable {

    @Override
    public void run() {
        runOnUiThread(() -> increaseCounter());
        try {
            Thread.sleep(7000);
            Log.d("task2", "run: ");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            runOnUiThread(() -> decreaseActiveCounter());
        }
    }
}

谢谢,在提供的示例中它确实起作用。是否有任何方法可以在显示progressBar的同时保留终止功能?我使用wait termination的原因是等待所有必要的数据加载,然后才显示在UI中。当activeTaskCoubter变为零时,您可以显示数据,因为它已加载。它与等待终止相同,但异步。