gpt4 book ai didi

java - 在调用 removeCallbacks() 时,在新线程上启动的可运行对象不会停止

转载 作者:行者123 更新时间:2023-11-30 11:27:57 26 4
gpt4 key购买 nike

我有以下代码。

//This is global for the activity.
Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
//update the UI
}
};

在我的 onResume() 中,我启动了一个运行 runnable 的新线程。

protected void onResume()
{
super.onResume();

Thread t = new Thread(runnable);
t.start();
}

我的可运行程序如下:

Runnable runnable = new Runnable()
{
public void run()
{
// some networking stuff
// some db stuff
// whatever


handler.sendEmptyMessage(0);
handler.postDelayed(new Runnable()
{
public void run()
{
new Thread(runnable).start();
}
}, 30000);
}
}

我在 onPause() 里面有这个:

protected void onPause()
{
super.onPause();
handler.removeCallbacks(runnable);
}

最后,我调用了 handler.sendEmptyMessage(0); 以便调用 handleMessage(Message msg) 并更改了 UI,然后重复任务但启动一个新的可运行对象,它启动一个运行与此相同的可运行对象的新线程。

澄清问题:

  1. 我在我的 onResume() 中启动一个新线程,这意味着可运行对象不在 UI 线程上运行,但是,处理程序是在 UI 线程上创建的,并且自然地附加到 UI 线程. UI 如何完美更改?

  2. 它应该用于 handler.removeCallbacks(runnable),但是,每当我最小化应用程序时,runnable 仍然每 30 秒运行一次。 (这可能是因为它在一个新线程上,与创建的处理程序无关)。我怎样才能让它停止?

最佳答案

public class MainActivity extends Activity {

public static final int UPDATE = 1;
public static final int WORK = 2;

private Handler uiHandler = new Handler() {

@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE:
// Perform UI updates here
....
// UI Updates done, schedule WORK in 30 seconds:
this.sendMessageDelayed(this.obtainMessage(WORK), 30000);
break;
case WORK:
new Thread(doWork).start();
break;

default:
super.handleMessage(msg);
}
}

};

private WeakReference<Handler> handlerRef = new WeakReference<Handler>( uiHandler );

private Runnable doWork = new Runnable() {

@Override
public void run() {
// This will run on a different thread.

// If UI is still around, tell it to update
Handler ui = handlerRef.get();
if( ui != null )
ui.sendEmptyMessage(MainActivity.UPDATE);
}
};

@Override
protected void onPause() {
uiHandler.removeMessages(WORK);
super.onPause();
}

@Override
protected void onResume() {
super.onResume();
// Resume UI updates in 500ms, allowing UI to settle
uiHandler.sendMessageDelayed(uiHandler.obtainMessage(WORK), 500);
}

....
}

此模式在 UI 线程上使用单个处理程序。后台工作在 Runnable 中完成,ui 处理程序会将其发布到新线程,从而避免 NetworkOnMainThreadException 和——更重要的是——无响应的 UI。此外,在后台进程完成后 30 秒安排新的更新,以避免长时间运行的更新对系统造成负担。后台线程对 ui 处理程序使用 WeakReference,因此如果 Activity 在线程工作时被终止,它不会向其发送 UI 更新。

关于java - 在调用 removeCallbacks() 时,在新线程上启动的可运行对象不会停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19095242/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com