Обработчик, выбрасывающий NullPointerException через несколько часов - PullRequest
1 голос
/ 23 ноября 2010

В моем приложении у меня есть служба, которая использует обработчик для выполнения runnable через случайное количество времени.Программа работает отлично - на несколько часов.Внезапно программа выдаст 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)

Кроме того, как только приложение закрывается, я могу перезапустить приложение, и исключение не будет выброшено для другогонесколько часов.Сокращенный код, относящийся к обработчику, выглядит следующим образом:

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 Ответ

0 голосов
/ 30 июля 2011

У меня была очень похожая проблема, потому что я только создавал экземпляры 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
 }

Теперь, если по ошибке ошибочно вызваны мои обратные вызовы remove, исключение перехватывается и не вызывает принудительное закрытие.

Возможно, что postDelayed иногда не запускался из-за невыполнения определенных условий, или до того, как postDelayed был запущен, система могла уничтожить службу, вызывая вызов обратных вызовов в ondestroy. Таким образом, если вы поместите его в блок try, то, хотя removecallbacks все еще может потерпеть неудачу, это не повлияет на пользователя

Я знаю, что об этом спрашивали 8 месяцев назад, но я подумал, что мой ответ может помочь кому-то еще. :) Надеюсь, это поможет.

...