不频繁的 Handler.post 会导致巨大的丢帧和崩溃



我有一个简单的线程监听UDP广播来发现我的网络上的设备。当它接收到广播时,它在UI线程上发送一个Runnable到一个Handler,将设备的IP添加到一个ArrayList。最多每2秒接收一次报文。我已经验证了帖子每2秒才会出现一次。

我的应用程序也有一些片段。每当我在片段之间切换使用NavController.navigate()时,我从100-400帧下降和anr中得到任何地方。当我禁用线程,或者甚至只是禁用搜索重复并将设备添加到ArrayList时,帧丢失消失,但搜索和添加花费不到1ms(根据调试打印)。

我读了一堆关于Handlers问题的其他线程,但没有一个有帮助。你知道为什么我的帖子会导致这么多的帧下降吗?

下面是线程的run方法:

public void run(){
try {
DatagramSocket ds = new DatagramSocket(DISCOVERY_PORT);
ds.setSoTimeout(500);
ds.setBroadcast(true);
byte[] rxBuffer = new byte[1024];
DatagramPacket dp = new DatagramPacket(rxBuffer,rxBuffer.length);
while (!this.isInterrupted()) {
try {
ds.receive(dp);
String msg = new String(rxBuffer, 0, dp.getLength());
dp.setLength(rxBuffer.length);
callbackH.post(new Runnable() {
@Override
public void run() {
addGeophone(dp.getAddress().toString(),Integer.parseInt(msg));
}
});
}
catch (SocketTimeoutException e){
continue;
}
}
ds.close();
}
catch(Exception e){
e.printStackTrace();
}
}

和addGeophone函数被发送到UI线程:

private static void addGeophone(String ipAddress, int id){
boolean geophoneFound = false;
Geophone g;
//REMOVE BELOW HERE AND EVERYTHING SPEEDS UP.
for (int i = 0; i < geophones.size(); i++){
g = geophones.get(i);
if (g.id == id){
geophoneFound = true;
}
}
if (!geophoneFound) {
geophones.add(new Geophone(ipAddress, id));
}
}

如果从另一个线程执行,看起来DatagramPacket.getAddress()需要很长时间。当我将getAddress调用移动到海报线程时,一切都加快了。

public void run(){
try {
DatagramSocket ds = new DatagramSocket(DISCOVERY_PORT);
ds.setSoTimeout(500);
ds.setBroadcast(true);
byte[] rxBuffer = new byte[1024];
DatagramPacket dp = new DatagramPacket(rxBuffer,rxBuffer.length);
while (!this.isInterrupted()) {
try {
ds.receive(dp);
String msg = new String(rxBuffer, 0, dp.getLength());
dp.setLength(rxBuffer.length);
String ipAddress = dp.getAddress().toString();
callbackH.post(new Runnable() {
@Override
public void run() {
addGeophone(ipAddress,Integer.parseInt(msg));
}
});
}
catch (SocketTimeoutException e){
continue;
}
}
ds.close();
}
catch(Exception e){
e.printStackTrace();
}
}

最新更新