这最近一直在杀我。我正在制作一个快速设置磁贴,它应该显示为活动或非活动状态,具体取决于它是否可以通过套接字与特定计算机进行通信。以下是我的声明:
public class WakeUpTileService extends TileService {
private static volatile boolean online;
private final TimerTask timerTask;
private Timer timer;
这是构造函数:
public WakeUpTileService() {
super();
online = true;
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
boolean shouldBeOn = false;
try {
Socket s = new Socket();
// 3000 is the timeout in milliseconds.
s.connect(myInetSocketAddress, 3000);
// Connection was successfully established.
s.close();
shouldBeOn = true;
} catch (Exception e) {
// Connection failed.
// shouldBeOn is already false.
} finally {
if (shouldBeOn != WakeUpTileService.online) {
WakeUpTileService.online = shouldBeOn;
// This method causes onStartListening() to be called
// on the main thread so I can update the Tile.
requestListeningState(
getApplicationContext(),
new ComponentName(
getApplicationContext(),
WakeUpTileService.class
)
);
}
}
}
};
}
这是计时器启动的地方:
@Override
public void onTileAdded() {
super.onTileAdded();
timer.scheduleAtFixedRate(timerTask, 0, 60000);
// At the moment I have it checking once per minute
// For debugging purposes. I plan to make it less frequent.
}
这是使用online
的值来更新Tile的代码。这会在WakeUpTileService.online = shouldBeOn;
中的TimerTask
之后在主线程上调用。
@Override
public void onStartListening() {
Tile t = getQsTile();
if(WakeUpTileService.online)
t.setState(Tile.STATE_ACTIVE);
else
t.setState(Tile.STATE_INACTIVE);
t.updateTile();
}
当我逐步调试调试器中的代码时,TimerTask
代码肯定在onStartListening
被调用之前完成,并且在TimerTask
的上下文中,online
成立正确的价值。然后,当onStartListening
被调用时,online
似乎恢复到它在开头时的值。
我已经了解了可能发生的事情:
WakeUpTileService中引用的online
在某种程度上与Runnable代码中引用的对象不同(这就是为什么我使online
静态并使用WakeUpTileService.online
代替只是online
。)
在online
读取online
之前,实际上没有发生onStartListening()
的分配。再次,当我使用调试器执行代码时,这似乎没有发生,只是通过查看下面的代码,这似乎不合理。
我不知道这里还会发生什么。请帮忙!
更新:korolar建议这两个类可能已被不同的类加载器加载,经过一些调查后,我发现是的原因。我的服务由dalvik.system.PathClassLoader
加载,java.util.Timer
正在加载java.lang.BootClassLoader
。但是,我不知道如何解决或解决这个问题。任何人都可以提供一些建议吗?
答案 0 :(得分:0)
如果有其他人遇到这个问题,我会告诉你我最终做了什么来修复它。
在Android编程中,显然使用java.util.Timer类通常是不好的做法。相反,我使用Android AlarmManager
类和IntentService
重写了我的程序。这完全绕过了类加载器问题。