我正在对Android应用程序崩溃进行验尸,我的推理无法解释应用程序如何在这种情况下结束。
由于这是一个制作应用程序,它使用ProGuard进行了混淆,我愚蠢到丢失了应用程序特定版本的映射文件。然而,通过一些伏都教魔法,我能够从中找到答案:
0 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
1 at com.einpix.android.a.a.a.a(Unknown Source)
2 at com.einpix.android.d.f.a(Unknown Source)
3 at com.einpix.android.d.f.a(Unknown Source)
4 at com.einpix.android.f.g.a(Unknown Source)
5 at com.einpix.android.d.g.onLocationChanged(Unknown Source)
6 at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:290)
...
问题实际发生在equals(...)
方法中:
public abstract class Entity
{
private static final String TAG = "Entity";
protected int localId;
protected int remoteId;
public Entity(int localId, int remoteId)
{
this.localId = localId;
this.remoteId = remoteId;
}
public int getId()
{
return getLocalId();
}
public int getLocalId()
{
return localId;
}
public int getRemoteId()
{
return remoteId;
}
public void setLocalId(int id) {
this.localId = id;
}
public void setRemoteId(int id)
{
this.remoteId = id;
}
public boolean equals(Entity other)
{
if (other == null) {
return false;
}
if (App.DEBUG) Log.d(TAG, "equals: " + this.getClass().getCanonicalName() + " vs " + other.getClass().getCanonicalName() + " --> " + (other.getClass().getCanonicalName().equals(this.getClass().getCanonicalName()) ? "Y":"N"));
if (!other.getClass().getCanonicalName().equals(this.getClass().getCanonicalName())) {
return false;
}
if (App.DEBUG) Log.d(TAG, "equals-localId: " + this.getLocalId() + " vs " + other.getLocalId() + " --> " + (this.getLocalId() == other.getLocalId() ? "Y":"N"));
if (this.getLocalId() == other.getLocalId() && this.getLocalId() > 0) {
return true;
}
if (App.DEBUG) Log.d(TAG, "equals-remoteId: " + this.getRemoteId() + " vs " + other.getRemoteId() + " --> " + (this.getRemoteId() == other.getRemoteId() ? "Y":"N"));
if (this.getRemoteId() == other.getRemoteId() && this.getRemoteId() > 0) {
return true;
}
return false;
}
}
(有一个逻辑顺序通往这个地方,这是我的代码中实际使用.getClass()
的少数几个地方之一)
所以我的问题是,考虑到这个方法被调用(因此this
不能以任何方式为空)并且第一次if
检查是否other
为空 - 如何可能是因为某些时候在这两个中的一个上调用.getClass
导致NullPointerException
?
P.S。在发布应用之前,App.DEBUG
设置为false
,因此在这种情况下它是一个安全的假设。但是,为了完整起见,我将这些线留在这里。
更新
对此方法的调用来自以下一级if子句:
if (currentClosest != null && !currentClosest.equals(lastClosest) && !currentClosest.equals(currentChosen))
currentClosest
,lastClosest
和currentChosen
是public class Venue extends Entity
的实例(或可能为空)
显然,在我的Venue
课程中,我定义了另一个equals()
方法:
@Override
public boolean equals(Object o)
{
if (!(o instanceof Venue)) {
return false;
}
Venue v = (Venue) o;
return (this.getLocalId() == v.getLocalId() || this.getRemoteId() == v.getRemoteId());
}
这是愚蠢和不必要的,但我不知道它如何在这个崩溃案件中扮演任何角色。此方法没有对.getClass()