Andriod后台线程不断监听UDP端口

时间:2019-03-04 11:13:36

标签: java android

非常感谢您花几分钟阅读我的问题,在此先感谢您!

我正在为某些特定用户构建非公开应用,这是我的问题:


我有一项针对后台工作负载的服务,其中启动了一个用户线程,该线程不断侦听UDP端口。设备屏幕打开时,它工作正常,但屏幕关闭时,它丢失了所有UDP数据包。

以下是我在线程中写的内容:

// Android os v7.1.2, wifi 
DatagramSocket s;
DatagramPacket p;  // already initialized 
while (true) {
    try {
        if (s == null || !s.isBound()) {
            s = new DatagramSocket(60000);
            s.setSoTimeout(0);
        } else {
            s.receive(p);  
            ... 
        }
    } catch(Exception e) {
        ...
    }
}

我想这是Android设备上与电源管理相关的问题。我曾尝试在while循环之前和之后放置 PowerManager.WakeLock.aquire() release(),但这确实有效。

需要明确的是,此应用是为特定客户端构建的,并不关心会消耗多少电池(可能是大多数情况下设备上唯一正在运行的应用)。

任何想法我该怎么办?我应该选择 IntentService 还是类似的方法来实现这种“无限的” UPD端口监听工作?我花了整整一个周末的时间在Android文档中寻找解决方案,但是没有一个例子表明我可以立即触发UDP套接字监听[悲伤的表情]。

有关更多信息,我记录了在服务中启动的所有三个套接字连接线程,发现使用tcp套接字将sth发送到服务器并等待sth返回的一个线程工作得很好...

1 个答案:

答案 0 :(得分:0)

我们开发了具有类似要求的SIP应用程序。

有一项重要设置,您的用户必须使用其设备,而您无法在应用程序中执行此操作。

他们需要转到设置->数据->背景数据,然后打开“无限背景数据”。 此外,他们还应将应用置于“未优化”状态以优化电池,这样,如果Android不断消耗电池电量,它就不会杀死它/使其进入睡眠状态。 这些都是设置,应用程序根本无法做到。它必须由用户完成。

此外,您说得很对,仅使用CPU的Wakelock(即没有TURN_SCREEN_ON标志)是一种方法。

但是您应该避免“永远”打开唤醒锁,因为android可能会杀死它。

我会做这样的事情:

    1. 获取超时为30秒的唤醒锁“ 1”
    1. 25秒后,获取唤醒锁“ 2”,并让“ 1”用尽。
    1. 再过30秒,再次获取“ 1”,并让“ 2”超时。
    1. 返回第2步。

这是一个后台线程,它将在第一个唤醒锁超时之前重新获取另一个唤醒锁。

希望您能明白。