我已经看到了很多奇怪的错误,但这次,我完全被难住了。尝试调用同一类中的方法时出现 NullPointerException。
首先,一些代码。让我们从违规行开始。当然,该方法比这更长,但这是它的开始以及所有相关的内容:
protected synchronized void checkTransfers() {
if (isPaused())
return;
}
isPaused
是一个简单的 getter 方法:
protected boolean isPaused() {
return paused.get();
}
为了完整起见:
protected AtomicBoolean paused = new AtomicBoolean(false);
现在的问题是这段代码大约有 50% 的运行时间,它只是在 if (isPaused())
行上抛出一个 NullPointerException,这对我来说毫无意义。 checkTransfers()
方法与 isPaused()
在同一个类中。我的同事试图通过提及问题可能出在所涉及的多线程中来帮助我,例如,如果另一个线程获得了 CPU 时间并删除了它对该对象的引用,但该对象永远不会在我的代码中的任何地方丢失其引用。另外:一旦 NPE 触发,this
仍然正确定义。
堆栈跟踪如下:
main@830013674640" prio=5 runnable java.lang.Thread.State: RUNNABLE at 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) at android.os.AsyncTask.finish(AsyncTask.java:602) at android.os.AsyncTask.access$600(AsyncTask.java:156) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:4945) at java.lang.reflect.Method.invokeNative(Method.java:-1) at 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)
checkTransfers()
中的第 125 行是上面的 if 语句。
有谁知道什么会导致这样的行为?
最佳答案
是的,经过了一些邪恶的调试,但我似乎找到了问题所在。发布它以防它以后可以帮助其他人。
首先,您需要进一步了解我的方法。这是完整的:
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 都知道它们的调用 Activity,以便它们可以显示进度对话框,但 UploadTask 总是被传递 null
而不是对调用者的引用。在旧版本的代码中这很好,但在最近的一些更改之后,显然它成为了一个问题。
我仍然不确定为什么每当我的任务试图访问对其调用 Activity 的不存在引用时我没有得到异常,但显然在看似无关的代码中触发异常是正常行为.
感谢您花时间阅读我的问题并尝试提供帮助。我希望至少我的回答对其他人有帮助。
关于java - 对同一类中方法的无参数调用产生 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18314585/