2

Я видел свою долю странных ошибок, но на этот раз я полностью в тупике. Я получаю исключение NullPointerException при попытке вызвать метод в том же классе.Бесполезный вызов метода в том же классе дает NullPointerException

Прежде всего, некоторые из кода. Начнем с оскорбительной линии. Метод, конечно, больше, чем это, но это начало его, и все, что имеет отношение:

protected synchronized void checkTransfers() { 
    if (isPaused()) 
     return; 
} 

isPaused простой метод геттер: сак

protected boolean isPaused() { 
    return paused.get(); 
} 

И для полноты:

protected AtomicBoolean paused = new AtomicBoolean(false); 

Теперь проблема заключается в том, что около 50% от времени этот код выполняется, он просто бросает NullPointerException на if (isPaused()) линии, которая не имеет никакого смысла для меня. Метод checkTransfers() относится к классу isPaused(). Мой коллега попытался помочь мне, упомянув, что проблема может заключаться в многопоточности, которая задействована, если, например, другой поток получил время процессора и удалил ссылку на объект, но объект никогда не должен потерять ссылку в любом месте моего кода. Также: this по-прежнему правильно определяется после срабатывания NPE.

StackTrace выглядит следующим образом:

Главный @ 830013674640" PRIO = 5 работоспособный java.lang.Thread.State: Runnable на com.omines.android.communicationmanager.CommunicationManager.checkTransfers (CommunicationManager. java: 125) at com.omines.android.communicationmanager.DownloadTask.onPostExecute (DownloadTask.java:105) at com.omines.android.communicationmanager.DownloadTask.onPostExecute (DownloadTask.java:20) на android.os. AsyncTask.finish (AsyncTask.java:602) на android.os.AsyncTask.access $ 600 (AsyncTask.java:156) на android.os.AsyncTask $ InternalHandler.handleMessage (AsyncTask.java:615) на android.os.Handler.dispatchMessage (Handler.java:99) на android.os.Looper.loop (Looper.java:154) на android.app.ActivityThread.main (ActivityThread.java:4945) на java.lang.reflect.Method.invokeNative (Method.java:-1) на java.lang.reflect.Method.invoke (Method.java : 511) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:551) at dalvik.system .NativeStart.main (NativeStart.java:-1)

Строка 125 в checkTransfers() является выражением if выше.

Кто-нибудь может понять, что может вызвать подобное поведение?

+0

Я только что нашел [this] (http://stackoverflow.com/questions/12070118/nullpointerexception-thrown-in-java-synchronised-method-using-sockets) вопрос, который, как представляется, связан. Сначала попробуем и сделаем это. –

+2

Вы пробовали сделать «приостановленный» финал? – Fildor

+0

У меня сейчас, но это, похоже, не имеет никакого значения. Спасибо за предложение. –

ответ

1

Правильно, потребовалась некоторая злая отладка, но я, похоже, нашел проблему. Отправляйте его, если он может помочь кому-то еще позже.

Во-первых, вам нужно знать немного больше о моем методе. Это полный:

protected synchronized void checkTransfers() { 
    if (isPaused()) 
     return; 
    while (transferQueue.peek() != null && (transferQueue.peek().priority == PRIORITY_URGENT || 
      (transferSemaphore.availablePermits() > maxConcurrentTransfers))) 
    { 
     CommunicationTask ct = transferQueue.poll(); 
     if (ct != null) 
     { 
      if (ct instanceof DownloadTask) 
       currentlyDownloading.add((DownloadTask)ct); 
      ct.execute(); 
     } 
    } 
} 

Я выяснил, что он не будет генерировать исключение в начале метода.Как выясняется, до исключения он будет проходить через весь метод один раз, а затем вместо выхода из него отладчик будет прыгать в первую строку метода и выкидывать исключение NullPointerException.

С чем-то в руке, с которым можно работать, я узнал, что это произошло, когда не была загружена DownloadTask, но UploadTask. Как оказалось, все мои DownloadTasks знали свою активность вызова, чтобы они могли показывать диалоги прогресса, но UploadTask всегда передавался null вместо ссылки на вызывающего. В старой версии кода это было хорошо, но после некоторых недавних изменений, по-видимому, это стало проблемой.

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

Спасибо, что нашли время, чтобы прочитать мой вопрос и попытаться помочь. Надеюсь, хотя бы мой ответ помогает кому-то другому.