公共类MyApplication扩展应用程序导致的java.lang.NullPointerException
在检查我的Android应用程序崩溃报告时,我注意到,公共类MyApplication扩展应用程序导致的java.lang.NullPointerException,java,android,nullpointerexception,singleton,extends,Java,Android,Nullpointerexception,Singleton,Extends,在检查我的Android应用程序崩溃报告时,我注意到,java.lang.NullPointerException是导致崩溃的主要原因之一。这是我经常发生的车祸的一个例子: java.lang.RuntimeException: at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3364) at android.app.ActivityThread.handleLaun
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
,这是用于维护全局应用程序状态的基类,如中所述。我正在子类化应用程序:
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
,但并非总是如此。我的理论是,我的应用程序所发生的情况如下所述:
但是,决不应将可变实例数据存储在
应用程序
对象,因为如果您假定数据将保留
在这种情况下,您的应用程序将不可避免地在某个时候崩溃,并出现错误
NullPointerException
。应用程序对象不保证保留
在永远的记忆中,它会被杀死。与人们普遍认为的相反,这一观点是错误的
应用程序不会从头重新启动。Android将创建一个新的
应用程序
对象并在用户之前所在的位置启动活动
给人一种错觉,认为应用程序在第一次测试中从未被杀死
地点
我尝试使用以下方法登录:
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()值的原始对象.p详细信息
已正确分配。因此,我的解释是,即使我希望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.
.....
}
}
嗯,是的,您认为应用程序实例可以被终止的假设是正确的。你有时犯的错误就是证明。正如本文所说:
操作系统可能会根据需要终止进程。所有流程分为5个级别的“可杀灭性”,具体如下所示
因此,例如,如果您的应用程序由于用户接听来电而进入后台,那么根据RAM的状态,操作系统可能(也可能不会)终止您的进程(在进程中销毁应用程序实例)
您的应用程序实例作为存储类用例不可靠。例如,让我们举一个例子:
- 你的应用程序进入后台,因为你的用户已进入应用程序主抽屉,或者你的应用程序正在消耗不必要的内存或电池
- 文档中说,因为你的应用程序在后台,所以你的服务,或者有时应用程序状态为“已取消”
这就是为什么在应用程序实例中没有那么多存储数据的方法。大多数情况下,您会使用或将其写入本地文本、自定义文件。这篇文章包含了更多的信息:关于根本原因的详细解释。根据该条,这是解决方案:
这里没有神奇的解决方案,您可以执行以下操作之一:
通过intent显式地将数据传递给活动李>
使用多种方法之一将数据持久化到磁盘李>
始终执行空检查并手动处理
您的ProductDetail
类是什么?@GauravMall查看我的update1
。那么,您是否定义过pDetail
?另外,您是否在清单中声明了您的MyApplication
类?很好,知道您在寻找什么。等等,有没有关于什么时候,什么时候,什么地方会被杀死的命令?应用程序是第一个还是如何工作?是的,有。Android将每个服务都放在一个重要级别上。一旦某件事情变得不重要,android就会将其扼杀。请看以下文档: