简体   繁体   English

在Android上,如果按下后退按钮,可运行线程会如何处理?

[英]On Android what happens to Runnable thread when back button pressed?

I have a Runnable (say " MyThread ") that executes a long task and also uses/locks a Thread-Safe Singleton. 我有一个Runnable(例如“ MyThread ”),它执行一个长任务,并且还使用/锁定一个线程安全的Singleton。

I have noticed that when the back button is pressed the screen immediately exits the activity and there is no visual indication that the MyThread has properly finished. 我注意到,当按下“后退”按钮时,屏幕立即退出活动,并且没有视觉指示MyThread已正确完成。

This is evidenced also by the fact that when I 'reopen' my app the singleton is still locked!!!! 当我“重新打开”我的应用程序时,单例仍然被锁定!!!! and of course getLockedInstance() returns null. 当然, getLockedInstance()返回null。

So I guess my question is.... what exactly happens to android applications when the back button is pressed even when it is executing critical tasks? 因此,我想我的问题是...。 即使执行关键任务,即使按下后退按钮,Android应用程序也会发生什么? Are the threads terminated? 线程是否终止? Are the threads of the activity frozen and therefore all data being accessed and used? 活动的线程是否冻结,因此所有数据都被访问和使用? How do we ensure critical tasks are allowed to finish executing? 我们如何确保允许关键任务完成执行?

// 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();
    }
}

The Thread class in Android is no different from the Thread class in regular Java programming. Android中的Thread类与常规Java编程中的Thread类没有什么不同。 It is the closest representation of the underlying Linux native thread an application gets. 它是应用程序获取的底层Linux本机线程的最接近表示。 The Thread class creates the execution environment for tasks, represented by Runnable. Thread类创建由Runnable表示的任务的执行环境。 The Thread implements Runnable, so the task to be executed is either defined by the thread itself or injected during thread creation. 线程实现了Runnable,因此要执行的任务要么由线程本身定义,要么在线程创建期间注入。

线程的生命周期

When the run method has finished execution, the thread is terminated and its resources can be freed. 当run方法完成执行后,线程将终止,并且可以释放其资源。 This is the final state of the thread; 这是线程的最终状态。 no re-use of the Thread instance or its execution environment is possible. 不能重复使用Thread实例或其执行环境。

Interruptions (such as pressing back button) 中断 (例如按返回按钮)

Occasionally, an application wants to terminate the thread's execution before it has finished its task. 有时,应用程序希望在完成任务之前终止线程的执行。 For instance, if a thread is taking a long time to download a video and the user presses a button to cancel the download, the UI thread captures the button press and would like to terminate the downloading thread. 例如,如果某个线程要花很长时间下载视频,并且用户按下按钮来取消下载,则UI线程会捕获按钮的按下,并希望终止下载线程。 There is, however, no way a thread can be directly terminated. 但是,无法直接终止线程。 Instead, threads can be interrupted, which is an request to the thread that is should terminate, but it is the thread itself that determines whether to oblige or not. 取而代之的是,线程可以被中断,这是对应该终止的线程的请求,但是由线程本身来决定是否强制执行。 Interruptions are invoked on the thread reference: 在线程引用上调用中断:

Thread interruption is implemented collaboratively: the thread makes itself available to be interrupted, and other threads issue the call to interrupt it. 线程中断是通过协作实现的:线程使自己可以被中断,而其他线程则发出调用以将其中断。 Issuing an interruption has no direct impact on the execution of the thread; 发出中断对线程的执行没有直接影响。 it merely sets an internal flag on the thread that marks it as interrupted. 它仅在线程上设置一个内部标志,将其标记为已中断。 The interrupted thread has to check the flag itself to detect the interruption and terminate gracefully. 被中断的线程必须检查标志本身以检测中断并正常终止。 A thread must implement cancellation points in order to allow other threads to interrupt it and get it to terminate. 线程必须实现取消点,以允许其他线程中断它并使其终止。

(Posted on behalf of the OP) . (代表OP张贴)

Thanks to everyone (and @AJ AJ) for their comments and help. 感谢每个人(和@AJ AJ)的评论和帮助。 I had misdiagnosed the problem and actually the problem was mine. 我误诊了问题,实际上是我的问题。

The thread does actually finish executing, but since it is a long process, access to the Storage object is blocked to whatever activity the app is resumed to. 该线程实际上确实完成了执行,但是由于这是一个漫长的过程,因此无论恢复应用程序的活动如何,都无法访问Storage对象。 My solution was to use a getLockedInstanceWait() function (see below) instead of the "lock and return" type previously utilized: 我的解决方案是使用getLockedInstanceWait()函数(见下文),而不是之前使用的“锁定并返回”类型:

public static Storage getLockedInstanceWait()
{
    Storage s = null;
    while ((s = Storage.getLockedInstance()) == null)
    {
        try
        {
            Thread.sleep(500);
        }
        catch (InterruptedException e)
        {
            return null;
        }
    }

    return s;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM