You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中调用自定义类的音频播放方法为何崩溃?

问题描述

我创建了一个包含音频播放方法的类:

import android.content.Context;
import android.media.MediaPlayer;

public class Sounds {

    private Context context;

    public void Sound(Context context) {
        this.context = context;
    }

    void hydrogen() {
        final MediaPlayer mp = MediaPlayer.create(context, R.raw.hydrogen);
        mp.start();
    }

}

我想通过以下代码实现点击按钮播放音频:

public void onClick(View view){
        Sounds s = new Sounds();
      s.hydrogen();
}

点击按钮时程序崩溃,但直接在MainActivity中编写播放代码时音频可以正常播放。我怀疑问题与从res文件夹获取音频文件有关,但不知道如何修复。我曾创建另一个仅定义变量的自定义类,调用其方法没有问题。Logcat中高亮了final MediaPlayer mp = MediaPlayer.create(context, R.raw.hydrogen);里的“create”关键字,以下是堆栈信息:

E  FATAL EXCEPTION: main
                                                                                                    Process: com.xxmassdeveloper.soundtest, PID: 14132
                                                                                                    java.lang.IllegalStateException: Could not execute method for android:onClick
                                                                                                        at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:473)
                                                                                                        at android.view.View.performClick(View.java:7870)
                                                                                                        at android.widget.TextView.performClick(TextView.java:14970)
                                                                                                        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219)
                                                                                                        at android.view.View.performClickInternal(View.java:7839)
                                                                                                        at android.view.View.access$3600(View.java:886)
                                                                                                        at android.view.View$PerformClick.run(View.java:29363)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:883)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:100)
                                                                                                        at android.os.Looper.loop(Looper.java:237)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7948)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
                                                                                                    Caused by: java.lang.reflect.InvocationTargetException
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:468)
                                                                                                        at android.view.View.performClick(View.java:7870) 
                                                                                                        at android.widget.TextView.performClick(TextView.java:14970) 
                                                                                                        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219) 
                                                                                                        at android.view.View.performClickInternal(View.java:7839) 
                                                                                                        at android.view.View.access$3600(View.java:886) 
                                                                                                        at android.view.View$PerformClick.run(View.java:29363) 
                                                                                                        at android.os.Handler.handleCallback(Handler.java:883) 
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:100) 
                                                                                                        at android.os.Looper.loop(Looper.java:237) 
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7948) 
                                                                                                        at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075) 
                                                                                                    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
                                                                                                        at android.media.MediaPlayer.create(MediaPlayer.java:1002)
                                                                                                        at android.media.MediaPlayer.create(MediaPlayer.java:981)
                                                                                                        at com.xxmassdeveloper.soundtest.Sounds.hydrogen(Sounds.java:15)
                                                                                                        at com.xxmassdeveloper.soundtest.MainActivity.onClick(MainActivity.java:48)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                        at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:468) 
                                                                                                        at android.view.View.performClick(View.java:7870) 
                                                                                                        at android.widget.TextView.performClick(TextView.java:14970) 
                                                                                                        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219) 
                                                                                                        at android.view.View.performClickInternal(View.java:7839) 
                                                                                                        at android.view.View.access$3600(View.java:886) 
                                                                                                        at android.view.View$PerformClick.run(View.java:29363) 
                                                                                                        at android.os.Handler.handleCallback(Handler.java:883) 
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:100) 
                                                                                                        at android.os.Looper.loop(Looper.java:237) 
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7948) 
                                                                                                        at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075) 
2023-01-27 10:29:00.836 14132-14132 Process                 com.xxmassdeveloper.soundtest        I  Sending signal. PID: 14132 SIG: 9
2023-01-27 10:29:00.912  3675-4184  WindowManager           pid-3675                             E  win=Window{57fa696 u0 com.xxmassdeveloper.soundtest/com.xxmassdeveloper.soundtest.MainActivity EXITING} destroySurfaces: appStopped=false win.mWindowRemovalAllowed=true win.mRemoveOnExit=true win.mViewVisibility=0 caller=com.android.server.wm.AppWindowToken.destroySurfaces:1200 com.android.server.wm.AppWindowToken.destroySurfaces:1181 com.android.server.wm.WindowState.onExitAnimationDone:5030 com.android.server.wm.-$$Lambda$01bPtngJg5AqEoOWfW3rWfV7MH4.accept:2 java.util.ArrayList.forEach:1262 com.android.server.wm.AppWindowToken.onAnimationFinished:3549 com.android.server.wm.AppWindowToken.commitVisibility:860 
问题原因

从堆栈信息里的java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference可以明确看出,是Sounds类里的context变量为null导致的崩溃。

问题出在Sounds类的构造方法上:你写的public void Sound(Context context)不是构造方法,只是一个普通的无返回值方法。构造方法的规则是方法名必须和类名完全一致,且不能有返回值类型(包括void)。所以当你调用new Sounds()的时候,执行的是默认的无参构造方法,并没有给context赋值,导致调用s.hydrogen()时context是空的。

修复方案

1. 修正Sounds类的构造方法

把原来的普通方法改成正确的构造方法:

import android.content.Context;
import android.media.MediaPlayer;

public class Sounds {

    private Context context;

    // 正确的构造方法:无返回值类型,方法名和类名一致
    public Sounds(Context context) {
        this.context = context;
    }

    void hydrogen() {
        final MediaPlayer mp = MediaPlayer.create(context, R.raw.hydrogen);
        mp.start();
        // 可选:播放完成后释放资源,避免内存泄漏
        mp.setOnCompletionListener(MediaPlayer::release);
    }

}

2. 修改点击事件中的调用代码

创建Sounds实例时传入当前Activity的Context:

public void onClick(View view){
        Sounds s = new Sounds(view.getContext());
        s.hydrogen();
}

或者直接用this(如果onClick方法在Activity内部):

public void onClick(View view){
        Sounds s = new Sounds(this);
        s.hydrogen();
}
额外建议
  • 每次使用MediaPlayer播放完成后,记得调用release()释放资源,避免内存泄漏。
  • 可以考虑对MediaPlayer.create()的返回值做非空判断,防止音频文件不存在时再次崩溃:
void hydrogen() {
    final MediaPlayer mp = MediaPlayer.create(context, R.raw.hydrogen);
    if (mp != null) {
        mp.start();
        mp.setOnCompletionListener(MediaPlayer::release);
    }
}

内容的提问来源于stack exchange,提问作者Binbows

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:01:21