【问题标题】:Thread runs sporadically when the screen is off屏幕关闭时线程偶尔运行
【发布时间】:2018-02-21 16:31:17
【问题描述】:

我有一个工作线程,它在活动启动时开始运行。它通过调用回调在屏幕打开时更新 UI 元素。现在,当应用在后台时,工作线程应该继续工作。

但是,关闭屏幕后线程变得不稳定。当屏幕打开时,线程会相当准确地执行它的工作循环,但屏幕关闭时情况并非如此。

我用于线程可运行的调试部分如下所示:

@Override
public void run()
{
    while(mRunning)
    {
        Log.i(TAG, "Tick");
        try
        {
            Thread.sleep(1000);
        }
        catch(InterruptedException e)
        {
            mRunning = false;
        }
    }
}

当我在屏幕打开时运行它时,logcat 输出相当一致:

11-21 15:15:18.022    1424-2260/com.manabreak.threadedtest I/Worker: Tick
11-21 15:15:19.031    1424-2260/com.manabreak.threadedtest I/Worker: Tick
11-21 15:15:20.030    1424-2260/com.manabreak.threadedtest I/Worker: Tick
11-21 15:15:21.031    1424-2260/com.manabreak.threadedtest I/Worker: Tick
11-21 15:15:22.037    1424-2260/com.manabreak.threadedtest I/Worker: Tick

如您所见,它非常准确,大约在 1000 毫秒内保持不变。但是,当屏幕关闭时,输出变得非常随机:

11-21 15:16:22.002    1424-2260/com.manabreak.threadedtest I/Worker: Tick
11-21 15:16:28.781    1424-2260/com.manabreak.threadedtest I/Worker: Tick
11-21 15:16:29.646    1424-2260/com.manabreak.threadedtest I/Worker: Tick
11-21 15:16:33.619    1424-2260/com.manabreak.threadedtest I/Worker: Tick
11-21 15:16:38.497    1424-2260/com.manabreak.threadedtest I/Worker: Tick

这是比较零星的。首先它休眠了将近 7 秒,然后在 900 毫秒内循环,然后又是 4 秒……如何让线程更“顺畅”地运行?工人应该相当准确和及时地工作。

【问题讨论】:

  • 也许你应该考虑在服务而不是线程中这样做。它更适合 Android 平台。

标签: java android multithreading


【解决方案1】:

我使用PARTIAL_WAKE_LOCK 解决了这个问题:

private WakeLock mWakeLock;

// Activity's onCreate()
@Override
protected void onCreate(Bundle savedInstanceState)
{
    ...
    PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
    mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "worker");
    ...

    // The worker thread
    Thread t = new Thread(mRunnable);
    t.start();
}

@Override
protected void onPause()
{
    super.onPause();
    mWakeLock.acquire();
}

@Override
protected void onResume()
{
    super.onResume();
    if(mWakeLock.isHeld()) mWakeLock.release();
}

如果您这样做,请记住将权限添加到您的清单中:

<uses-permission android:name="android.permission.WAKE_LOCK"/>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多