runOnUiThread()在从ThreadExecutor调用时会对已关闭的活动产生影响。

huangapple go评论74阅读模式
英文:

runOnUiThread() acts on a closed activity when called from ThreadExecutor

问题

我在使用 runOnUiThread() 时遇到一个在已关闭的活动上执行的问题。以下是逻辑:

在第一个活动中,我导航到第二个活动。

在第二个活动中,我正在进行一些后台获取操作,一旦完成,我就会导航到第三个活动。

问题是,如果我在数据仍在获取的情况下关闭第二个活动,我的线程会继续运行,由于我的代码中调用了 runOnUiThread(),活动一会被操作,然后导航到第三个活动。我不希望发生这种情况。我希望线程停止运行,或者至少在 runOnUiThread() 中的内容不会影响除创建线程的活动之外的任何其他活动。

注意:在我的示例中,它启动了一个活动,但其他与 UI 相关的代码也可能以相同的方式触发。

这是我的代码:

ExecutorService executorService = Executors.newSingleThreadExecutor();

executorService.execute(new Runnable() {
    public void run() {
        // 进行数据获取操作

	runOnUiThread(new Runnable() {
	        @Override
	        public void run() {
	            // 导航到第三个活动
	        }
	    });
    }
});

我尝试在活动关闭时关闭执行器服务,虽然我可以通过 console.log 语句验证 onDestroy() 被调用,但似乎 shutdown()shutdownNow() 都不起作用:

@Override
protected void onDestroy() {
    super.onDestroy();

    if (executorService != null) {
        executorService.shutdown(); // 无法停止线程执行
        executorService.shutdownNow(); // 无法停止线程执行
    }
}

编辑:我如何为此添加一个中断器以能够中断线程?

英文:

I am having an issue with runOnUiThread() acting on a closed activity. Here is the logic:

In activity one, I navigate to activity two.

In activity two I am doing some background fetching and once it is done, I navigate to activity three.

The issue is that if I close activity two while data is still being fetched, my thread keeps running and since runOnUiThread() gets called in my code, activity one gets acted on and it navigates me to activity three. I don't want that to happen. I want the thread to stop or at least for the things in runOnUiThread() to not touch any other activity besides the one that the thread was created in.

Note: In my example it is launching an activity but other code could be in there related to the UI that gets triggered in the same way.

Here is what my code looks like:

ExecutorService executorService = Executors.newSingleThreadExecutor();

executorService.execute(new Runnable() {
    public void run() {
        // Do fetching of data

	runOnUiThread(new Runnable() {
	        @Override
	        public void run() {
	            // Navigate to activity three
	        }
	    });
    }
});

I tried shutting down the executor service when the activity is closed, and while I can verify that onDestroy() gets called with a console.log statement, it appears neither shutdown() or shutdownNow() work:

@Override
protected void onDestroy() {
    super.onDestroy();

    if (executorService != null) {
        executorService.shutdown(); // Does not work to stop thread from executing
        executorService.shutdownNow(); // Does not work to stop thread from executing
    }

}

Edit: How do I add an interruptor to this to be able to interrupt the thread?

答案1

得分: 0

你需要在你的Runnable类内部添加一个ExecutorService.isShutdown()的检查。ExecutorService.shutdown()ExecutorService.shutdownNow()并不保证之前提交的任务会立即关闭。

根据文档,

ExecutorService.shutdown()
> 启动有序关闭,先前提交的任务将被执行,但不会接受新任务。如果已经关闭,调用不会有额外的效果。
> 该方法不会等待先前提交的任务完成执行。

ExecutorService.shutdownNow()
> 尝试停止所有正在执行的任务,停止等待任务的处理,并返回一个等待执行的任务列表。
>
> 该方法不会等待正在执行的任务终止。
>
> 除了尽力尝试停止正在执行的任务外,没有其他保证。例如,典型的实现将通过Thread.interrupt()来取消任务,因此任何无法响应中断的任务可能永远不会终止。

英文:

You will have to add a check of ExecutorService.isShutdown() inside your Runnable class. ExecutorService.shutdown() and ExecutorService.shutdownNow() does not guarantee that previously submitted task will be shut down immediately.

According to the documentation,

ExecutorService.shutdown()
> Initiates an orderly shutdown in which previously submitted tasks are
> executed, but no new tasks will be accepted. Invocation has no
> additional effect if already shut down.
> This method does not wait for previously submitted tasks to complete execution.

ExecutorService.shutdownNow()

> Attempts to stop all actively executing tasks, halts the processing of
> waiting tasks, and returns a list of the tasks that were awaiting
> execution.
>
> This method does not wait for actively executing tasks to terminate.
>
> There are no guarantees beyond best-effort attempts to stop processing
> actively executing tasks. For example, typical implementations will
> cancel via Thread.interrupt(), so any task that fails to respond
> to interrupts may never terminate.

huangapple
  • 本文由 发表于 2020年9月15日 08:58:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63893608.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定