【发布时间】:2019-08-22 18:32:36
【问题描述】:
在检查我的 Android 应用程序崩溃报告时,我注意到 java.lang.NullPointerException 是导致崩溃的主要原因之一。这是我经常崩溃的一个例子:
java.lang.RuntimeException:
at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3364)
at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3548)
at android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:86)
at android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2155)
at android.os.Handler.dispatchMessage (Handler.java:109)
at android.os.Looper.loop (Looper.java:207)
at android.app.ActivityThread.main (ActivityThread.java:7539)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:958)
Caused by: java.lang.NullPointerException:
at com.myapp.ProductDetails.onCreate (ProductDetails.java:47)
at android.app.Activity.performCreate (Activity.java:7441)
at android.app.Activity.performCreate (Activity.java:7431)
at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1286)
at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3343)
我去检查了我在com.myapp.ProductDetails.onCreate (ProductDetails.java:47) 中的内容,结果是这样的:
ProductDetail productDetail = MyApplication.getInstance().pDetail;
我知道该行导致了java.lang.NullPointerException 并因此导致崩溃。问题是为什么?我正在使用Application,这是https://developer.android.com/reference/android/app/Application 中解释的用于维护全局应用程序状态的基类。我正在继承应用程序:
import android.app.Application;
.....
public class MyApplication extends Application{
static MyApplication _instance;
public ProductDetail pDetail;
.....
@Override
public void onCreate() {
super.onCreate();
_instance= this;
.....
}
.....
public static MyApplication getInstance(){
return _instance;
}
}
但是当我使用ProductDetail productDetail = MyApplication.getInstance().pDetail; 时,有时我会得到java.lang.NullPointerException。我要强调的是,这条线有时会导致java.lang.NullPointerException,而不是一直。我的理论是,我的应用程序发生的事情是 https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class 解释的:
但是,您永远不应该将可变实例数据存储在
Application对象,因为如果您假设您的数据将保留 在那里,您的应用程序将不可避免地在某个时候崩溃NullPointerException。申请对象不保证留下 永远在记忆中,它会被杀死。与流行的看法相反, 应用程序不会从头开始重新启动。 Android将创建一个新的Application对象并启动用户之前的活动 给人一种应用程序一开始就没有被杀死的错觉 地点。
我尝试使用此日志记录:
ACRA.getErrorReporter().putCustomData("ACRA CUSTOM_DATA begins","ACRA CUSTOM_DATA begins");ACRA.getErrorReporter().putCustomData("MyApplication.getInstance()", MyApplication.getInstance().toString());ACRA.getErrorReporter().putCustomData("MyApplication.getInstance().pDetail", MyApplication.getInstance().pDetail.toString());ProductDetail productDetail = MyApplication.getInstance().pDetail;ACRA.getErrorReporter().putCustomData("ACRA CUSTOM_DATA ends","ACRA CUSTOM_DATA ends");
在日志结果中,我只看到这个:
CUSTOM_DATA=ACRA CUSTOM_DATA begins = ACRA CUSTOM_DATA begins
MyApplication.getInstance() = com.myapp.MyApplication@c190fea
我解释它的方式是MyApplication.getInstance().toString() 不会使应用程序崩溃,因为即使原始的MyApplication 丢失了(这是我的假设,如果进程在某个时候被杀死,那么该对象可能会丢失) 因为MyApplication.getInstance().toString() 创建了一个新对象,因为原始对象丢失了(我的假设)。但是当我尝试执行MyApplication.getInstance().pDetail.toString() 时,应用程序确实崩溃了,因为它已经丢失了成员变量pDetail 的值,因为MyApplication 将持有一个新对象,而不是原来的具有值的对象MyApplication.getInstance().pDetail 正确分配。所以我的解释是,即使我希望MyApplication.getInstance() 始终持有一个且只有一个对象,并且一直保持相同,直到我明确关闭应用程序,也许MyApplication 对象会丢失,然后使用MyApplication.getInstance() 创建一个新的目的。那么java.lang.NullPointerException 就有意义了。两个问题。 1. 你觉得这个解释合理吗?如果不是,为什么? 2. 你会建议做什么来重写我的代码,以便我修复这个我偶尔得到的java.lang.NullPointerException?有趣的是,当我长时间最小化应用程序(例如几小时或几天)然后重新打开它时,我已经看到这种情况发生在我身上。这是有道理的,因为也许进程被杀死了,当我将最小化的应用程序带回前台时,MyApplication.getInstance() 可能正在创建全新的进程或对象,而不是已经创建的原始进程或对象,因此,MyApplication.getInstance().pDetail本来已经失去了它的价值,然后我得到了java.lang.NullPointerException。这个理论有意义吗?
更新 1:
ProductDetail 是我拥有的一个类,其中包含导致崩溃的行和java.lang.NullPointerException:
public class ProductDetail extends FragmentActivity implements OnMapReadyCallback {
.....
static ProductDetail _instance;
protected void onCreate(Bundle savedInstanceState) {
.....
ProductDetail productDetail = MyApplication.getInstance().pDetail; // This is the line that SOMETIMES causes the app to crash with a java.lang.NullPointerException.
.....
}
}
【问题讨论】:
-
你的
ProductDetail班级是什么? -
@GauravMall 见我的
UPDATE 1。 -
嗯,你定义过
pDetail吗? -
另外,您是否在清单中声明了您的
MyApplication类? -
太好了,知道你在找什么。等一下
标签: java android nullpointerexception singleton extends