在Android上按下后退按钮时Runnable线程会发生什么?

时间:2016-09-21 23:59:57

标签: java android multithreading android-activity singleton

我有一个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();
    }
}

2 个答案:

答案 0 :(得分:1)

Android中的Thread类与常规Java编程中的Thread类没有什么不同。它是应用程序获得的底层Linux本机线程的最接近的表示形式。 Thread类为任务创建执行环境,由Runnable表示。 Thread实现Runnable,因此要执行的任务由线程本身定义或在线程创建期间注入。

Lifecycle of thread

当run方法执行完毕后,线程终止并且可以释放其资源。这是线程的最终状态;不能重用Thread实例或其执行环境。

中断(例如按后退按钮)

有时,应用程序希望在完成任务之前终止线程的执行。例如,如果线程花费很长时间来下载视频并且用户按下按钮以取消下载,则UI线程捕获按钮按下并且想要终止下载线程。但是,线程无法直接终止。相反,线程可以被中断,这是对应该终止的线程的请求,但是线程本身决定是否强制。在线程引用上调用中断:

线程中断是协同实现的:线程使其自身可以被中断,而其他线程发出调用来中断它。发出中断对线程的执行没有直接影响;它只是在线程上设置一个标记为中断的内部标志。被中断的线程必须检查标志本身以检测中断并正常终止。线程必须实现取消点,以允许其他线程中断它并使其终止。

答案 1 :(得分:0)

(代表OP发布)

感谢大家(和A. A.J A.J)的意见和帮助。我误解了这个问题,实际上问题是我的。

线程确实完成了执行,但由于它是一个很长的进程,因此对应用程序恢复的任何活动都会阻止对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;
}