Java 外部类中的本地字段不受可运行代码的影响
这件事最近让我很难受。我正在制作一个快速设置磁贴,根据它是否可以通过套接字与特定机器通信,该磁贴应显示为活动或非活动。以下是我的声明:Java 外部类中的本地字段不受可运行代码的影响,java,android,multithreading,Java,Android,Multithreading,这件事最近让我很难受。我正在制作一个快速设置磁贴,根据它是否可以通过套接字与特定机器通信,该磁贴应显示为活动或非活动。以下是我的声明: public class WakeUpTileService extends TileService { private static volatile boolean online; private final TimerTask timerTask; private Timer timer; 以下是构造函数: public Wake
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
的值来更新互动程序的代码。在wakeUpleService.online=shouldBeOn之后,在主线程上调用该函数在TimerTask
中的code>
@Override
public void onStartListening() {
Tile t = getQsTile();
if(WakeUpTileService.online)
t.setState(Tile.STATE_ACTIVE);
else
t.setState(Tile.STATE_INACTIVE);
t.updateTile();
}
当我在调试器中单步执行代码时,TimerTask
代码肯定在调用onstartstending
之前完成,并且在TimerTask
的上下文中,online
持有正确的值。然后,当调用onStartListening
时,online
似乎会恢复到开始时的值
我对可能发生的事情有过一些想法:
- WakeUpleService中引用的
online
与可运行代码中引用的对象不同(这就是为什么我将online
设置为静态,并使用WakeUpleService.online
而不仅仅是online
)
- 在
onStartListening()
读取online
之前,对online
的分配实际上不会发生。同样,当我使用调试器逐步处理代码时,这似乎没有发生,仅通过查看下面的代码,这似乎是不合理的
我不知道这里还会发生什么。请帮忙
更新:korolar建议这两个类可能是由不同的类加载器加载的,经过一些调查,我发现这就是原因。我的服务由dalvik.system.PathClassLoader
加载,java.util.Timer
由java.lang.BootClassLoader
加载。然而,我不知道如何解决这个问题。有人能提供一些建议吗?如果其他人遇到这个问题,我会告诉你我最终做了什么来解决它
显然,在Android编程中使用java.util.Timer类通常是不好的做法。相反,我使用AndroidAlarmManager
类和IntentService
重写了我的程序。这完全绕过了类加载器问题。如果其他人遇到这个问题,我会告诉你我最终做了什么来解决它
显然,在Android编程中使用java.util.Timer类通常是不好的做法。相反,我使用AndroidAlarmManager
类和IntentService
重写了我的程序。这完全绕过了类加载器问题。是onStartListening()
内部WakeUpleService
?是的,WakeUpleService
包含online
,timerTask
,一个名为Timer
的计时器对象,一个构造函数,@Override onTileAdded()
,@Override onStartListening()
,和@Override onClick()
。你说,“联机开始时为true”,但设置为true的代码在哪里?如果你使用最终原子布尔值而不是易失性布尔值,看看它是否能改善情况。可能吗,设置静态字段并读取它是在不同类加载器的上下文中执行的?是onStartListening()
内部WakeUpleService
?是的,WakeUpleService
包含online
,timerTask
,一个名为Timer
的计时器对象,一个构造函数,@Override onTileAdded()
、@Override-onstart-listening()
和@Override-onClick()
。你说“联机开始时为true”,但设置它为true的代码在哪里?如果你使用最终原子布尔值
而不是易失性布尔值
,看看它是否能改善情况。是否可能,设置静态字段并读取它是在不同类加载器的上下文中执行的吗?