在Android上按下后退按钮时Runnable线程会发生啥?
Posted
技术标签:
【中文标题】在Android上按下后退按钮时Runnable线程会发生啥?【英文标题】:On Android what happens to Runnable thread when back button pressed?在Android上按下后退按钮时Runnable线程会发生什么? 【发布时间】:2017-01-30 09:25:35 【问题描述】:我有一个 Runnable(比如“MyThread”),它执行一个长任务并使用/锁定一个线程安全的单例。
我注意到,当按下后退按钮时,屏幕会立即退出活动,并且没有视觉指示 MyThread 已正确完成。
当我“重新打开”我的应用程序时,单例仍然被锁定,这也证明了这一点!!!!当然 getLockedInstance() 返回 null。
所以我想我的问题是...... 即使在执行关键任务时按下后退按钮,Android 应用程序到底会发生什么? 线程是否终止?活动的线程是否被冻结,因此所有数据都被访问和使用?我们如何确保关键任务能够完成执行?
// singleton class
public class Storage
private int count = 0;
private static final Storage ourInstance = new Storage();
public static synchronized Storage getLockedInstance()
if (ourInstance.count > 0)
return null;
ourInstance.count++;
return ourInstance;
public synchronized void UnlockInstance()
if (count > 0)
count--;
// runnable declaration
private Runnable MyThread = new Runnable()
@Override
public void run()
Storage s = Storage.getLockedInstance();
..... do stuff .....
[back button pressed]
..... this is never reached .....
s.UnlockInstance();
【问题讨论】:
线程不一定会停止,但如果您的应用程序现在处于后台,则该进程可能会被终止。您是否尝试过在线程中添加日志调用?如果您绝对需要运行任务,请考虑将其放入Service
中,它将作为与您的应用程序分开的进程运行。
请从您的标题中删除“已解决”并将您找到的解决方案作为正确答案发布。
【参考方案1】:
android 中的 Thread 类与常规 Java 编程中的 Thread 类没有什么不同。它是应用程序获得的底层 Linux 本机线程的最接近的表示。 Thread 类为任务创建执行环境,由 Runnable 表示。 Thread实现了Runnable,所以要执行的任务要么由线程自己定义,要么在创建线程时注入。
当 run 方法完成执行后,线程被终止并且它的资源可以被释放。这是线程的最终状态;不能重复使用 Thread 实例或其执行环境。
中断(例如按下返回按钮)
有时,应用程序希望在线程完成任务之前终止线程的执行。例如,如果一个线程需要很长时间来下载视频并且用户按下按钮取消下载,UI 线程会捕获按钮按下并希望终止下载线程。但是,没有办法直接终止线程。相反,线程可以被中断,这是对应该终止的线程的请求,但线程本身决定是否执行。在线程引用上调用中断:
线程中断是协同实现的:线程使自己可以被中断,其他线程发出调用来中断它。发出中断对线程的执行没有直接影响;它只是在线程上设置一个内部标志,将其标记为中断。被中断的线程必须检查标志本身以检测中断并优雅地终止。一个线程必须实现取消点,以允许其他线程中断它并让它终止。
【讨论】:
我实现了一个 getLockedInstanceWait 函数(利用 Thread.sleep 方法),而不是一个“锁定并返回”类型的函数 getLockedInstance()。现在,虽然恢复活动时会有一点延迟,但最终存储对象会解锁并且我能够重新获得访问权限!这证实了你所说的 - 当活动或任何应用程序活动被恢复......然后Runnable(MyThread)也被恢复并且能够完成执行。感谢您的帮助。 @zdanman "这证实了你所说的 - 当活动或任何应用活动恢复时......然后 Runnable (MyThread) 也会恢复"您以错误的方式得到答案(从this book 复制/粘贴)。后台线程在按下后退按钮后继续运行,直到它们完成工作或进程被操作系统杀死。如果您想阻止后台线程,请参阅this 或使用Service
。
“中断(比如按下返回键)”你说的是什么类型的中断?
@Onik ,Anders Goransson 在他的书中提到,例如“如果用户按下按钮取消下载(即与按下返回按钮相同),这是一个中断示例。此外,您提到线程一直运行直到他们完成他们的工作,这重复了答案中提到的相同事情(但是,线程无法直接终止。当 run 方法完成执行时,线程被终止并它的资源可以被释放)【参考方案2】:
(代表 OP 发布)。
感谢大家(和@A.J A.J)的 cmets 和帮助。我误诊了问题,实际上是我的问题。
线程确实完成了执行,但由于它是一个漫长的过程,因此应用程序恢复到的任何活动都无法访问 Storage 对象。我的解决方案是使用 getLockedInstanceWait() 函数(见下文),而不是之前使用的“锁定并返回”类型:
public static Storage getLockedInstanceWait()
Storage s = null;
while ((s = Storage.getLockedInstance()) == null)
try
Thread.sleep(500);
catch (InterruptedException e)
return null;
return s;
【讨论】:
以上是关于在Android上按下后退按钮时Runnable线程会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章