Android:为什么Runnable在引用外部类方法时得到nullpointerexception?

时间:2014-11-20 07:57:43

标签: java android nullpointerexception

我遇到了一个奇怪的案例,这是我的示例代码。

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()) ..

时我仍然得到nullpointerexception

我认为有时MyMonitorService.this是由dalvik设置的,这是唯一可能的解释因为我已经使用try-catch保护整个run方法有任何异常......内部类是否有可能失去它外类参考?

1 个答案:

答案 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会停止所有调用的服务。