我遇到了一个奇怪的案例,这是我的示例代码。
public class MyMonitorService extends Service {
private MyMonitorManager mMyMonitorManager = new MyMonitorManager();
private Timer mTimer = new Timer();
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public boolean isHome(){
/**
* Sample code
*/
return true;
}
public void start(){
mTimer.schedule(r, 1000);
}
private TimerTask r = new TimerTask(){
@Override
public void run() {
try {
if(isHome()){
// xxxxx
}
} catch (Exception e) {
}
}
};
}
在某些自定义的ROM / Phone上,例如MIUI,虽然很少,但在执行if(isHome())
时我得到了nullpointerexception,并且应用程序崩溃了..
即使我将TimerTask更改为
private TimerTask r = new TimerTask(){
@Override
public void run() {
try {
if(mMyMonitorManager.isRunning()){
// xxxxx
}
} catch (Exception e) {
}
}
};
if(mMyMonitorManager.isRunning())
..
我认为有时MyMonitorService.this是由dalvik设置的,这是唯一可能的解释因为我已经使用try-catch保护整个run方法有任何异常......内部类是否有可能失去它外类参考?
答案 0 :(得分:0)
听起来您的服务正在被破坏,因此外部类不再可用。
由于您的服务从onBind返回null,我假设您要使用清单中的startService或intent过滤器来启动服务。但是你有一个onStartCommand方法吗?这是您应该执行服务工作的地方,该函数的返回值确定服务是否保持运行。
您的意图是在TimerTask运行时保持服务运行,然后停止它吗?在这种情况下,您可以从onStartCommand中启动TimerTask,返回START_STICKY,然后在TimerTask完成时停止服务。像这样:
public int onStartCommand(Intent intent, int flags, int startId) {
mTimer.schedule(r, 1000);
return START_STICKY;
}
private TimerTask r = new TimerTask(){
@Override
public void run() {
try {
if(isHome()){
// xxxxx
}
} catch (Exception e) {
} finally {
stopSelf();
}
}
};
这可能不够好,因为我猜测一次可能会有多个任务。在停止服务之前,您需要某种方式知道所有任务都已完成。即使您多次调用startService,第一次调用stopService或stopSelf会停止所有调用的服务。