Handler在几个小时后抛出NullPointerException

问题描述:

在我的应用程序中,我有一个服务使用一个处理程序在一段随机时间后执行一个runnable。该程序工作正常 - 几个小时。一旦Handler在几个小时后抛出NullPointerException

java.lang.NullPointerException 
at com.martin.ontime.OnTimeService$2.run(OnTimeService.java:224) 
at android.os.Handler.handleCallback(Handler.java:587) 
at android.os.Handler.dispatchMessage(Handler.java:92) 
at android.os.Looper.loop(Looper.java:144) 
at android.app.ActivityThread.main(ActivityThread.java:4937) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:521) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
at dalvik.system.NativeStart.main(Native Method) 

此外,由于应用强行关闭,我可以重新启动应用程序和异常不会被抛出另一个几个小时:突然的,程序将抛出一个NullPointerException异常与下面的跟踪。关于处理程序的缩写代码如下:

public class AppService extends Service{ 

/**XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

INITIATE ALL THE GLOBAL VARIABLES 

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ 

//Handler that times the processes 
private Handler h = new Handler(); 

/**XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ 







/**XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

    EXECUTE ALL CREATE FUNCTIONS 

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ 

@Override 
public void onCreate(){ 

    super.onCreate(); 

    //Clear all timers 
    h.removeCallbacks(setTime); 
    h.removeCallbacks(setAuto); 

    //Set a timer to start the processes 
    h.postDelayed(setAuto, 0); 

} 

/**XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/  







/**XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

    EXECUTE THESE FUNCTIONS WHEN SERVICE IS STOPPED 

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/  

@Override 
public void onDestroy(){ 

    //Clear all timers 
    h.removeCallbacks(setTime); 
    h.removeCallbacks(setAuto); 

} 

    /**XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/  





/**XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

    HANDLER RUNNABLE 

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/  

//Runnable 
private Runnable setAuto = new Runnable() { 

    public void run(){ 

    //Create a random number generator 
    Random r = new Random(); 

    //Determine a random amount of time until time is changed 
    long d = r.nextInt(5) * 60 * 1000; 

    //Wait 
    h.postDelayed(setTime, d); 

    } 

}; 

//Runnable used to set a random allowance 
private Runnable setTime = new Runnable() { 

    public void run(){ 

    try { 

    //Create a random number generator 
    Random r = new Random(); 

    //Determine a random amount of time until time is changed 
    long d = r.nextInt(30) * 60 * 1000 + 1800000; 

    //Wait 
    h.postDelayed(setAuto, d); 

          ***TRY/CATCH SURROUNDS A DATA OUTPUT STREAM*** 

    } 

    catch (IOException e){ 

    e.printStackTrace(); 

    } 

    } 

}; 

    /**XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/  
} 

我有另一个程序,它的服务中似乎也有这个问题。我只复制了涉及处理程序和可运行程序的代码,并由两个程序共享。我希望这是足够的信息来解决这个问题。如果需要更多信息,我肯定会填写一些空白。这将是这些和我未来的应用程序的很大帮助!

+1

OnTimeService.java的第224行在哪里? – 2010-11-23 06:37:53

我有一个非常类似的问题,因为我只在某些条件下实例化runnables,并且也只在某些条件下实际运行postDelayed。 对于实例

if (conditions){ 
    myRunnable = new Runnable(){ 
    @Override 
    public void run(){ 
    } 
    } 
myHandler.postDelayed(myRunnable, 1000*60*1); 
} 
@Override 
public void onDestroy(){ 
myHandler.removeCallbacks 
} 

为了确保这会不会导致强制关闭,我把它改成

@Override 
public void onDestroy(){ 
try { 
if (conditions) 
myHandler.removeCallbacks; 
} catch (Exception e){//do nothing 
} 

现在,如果错误地删除我的回调被误称为,异常被捕获并不强迫关闭。

由于未满足某些条件或postDelayed开始前,postDelayed有时可能不运行,系统可能已销毁该服务,导致调用ondestroy中的removecallbacks。所以,如果你把它放在try块中,那么虽然removecallbacks可能仍然失败,但不会对用户造成影响

我知道这是8个月前问的,但我认为我的答案可能有助于其他人。 :) 希望这会有所帮助。