为何在类初始位置初始化MediaPlayer会抛空指针,onCreate中则不会?
这个问题的核心其实是Android Activity的初始化时机和Context的生命周期在捣鬼,我来给你掰扯清楚:
当你在类的成员变量位置直接写private MediaPlayer player = MediaPlayer.create(this, R.raw.test);时,这个初始化代码会在Activity实例刚被创建,但系统还没给它绑定有效Context的时候执行。
先搞懂Activity的启动流程:
- 系统先创建Activity的对象实例,这时候类里的成员变量会被逐个初始化
- 然后系统才会调用
attachBaseContext()方法,把有效的Context绑定到Activity上 - 最后才会执行我们熟悉的
onCreate()方法
所以在成员变量初始化的阶段,this(也就是Activity本身)的Context还没准备好,相当于一个"空壳"。而MediaPlayer.create()内部需要调用Context.getResources()来加载音频资源,这时候Context是null,自然就抛出了NullPointerException——错误日志里那句Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference就是最好的证明。
为什么onCreate里初始化就没问题?
当你在onCreate()里写初始化代码时,super.onCreate(savedInstanceState)已经帮我们完成了Context的绑定工作,这时候this对应的是一个完全有效的Activity Context,调用MediaPlayer.create()自然能正常获取资源,不会出问题。
不止MediaPlayer,View等组件也一样
你提到的View等对象也有这个现象,本质原因相同:它们的创建都依赖Context来访问资源或系统服务,必须等Context初始化完成后才能调用相关方法。
正确的写法参考
public class MainActivity extends AppCompatActivity { // 先声明变量,暂不初始化 private MediaPlayer player; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 此时Context已就绪,放心初始化 player = MediaPlayer.create(this, R.raw.test); } }
内容的提问来源于stack exchange,提问作者user10624114

