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

Service播放音乐报错:mediaPlayer.setDataSource触发IllegalStateException

问题分析与修复方案

错误根源

  • 变量赋值顺序错误:先执行Toast展示未初始化的str(此时为null),之后才从Intent中获取uri赋值给str,导致setDataSource传入无效参数
  • MediaPlayer状态管理缺失:未重置MediaPlayer状态就重复设置数据源,当多次启动Service时,MediaPlayer处于非空闲状态,触发IllegalStateException
  • 缺少准备流程:设置数据源后未调用prepareAsync()/prepare(),MediaPlayer无法进入可播放状态

修复后的Service代码

public class MyService extends android.app.Service {
    private MediaPlayer mediaPlayer;
    private String str;
    private final IBinder binder = new LocalBinder();

    @Override
    public void onCreate() {
        super.onCreate();
        // onCreate中初始化MediaPlayer,避免重复实例化
        mediaPlayer = new MediaPlayer();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 优先获取Intent中的uri参数
        str = intent.getStringExtra("uri");
        if (str == null || str.isEmpty()) {
            Toast.makeText(this, "无效音频地址", Toast.LENGTH_SHORT).show();
            return START_STICKY;
        }
        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();

        try {
            // 重置MediaPlayer到空闲状态,避免重复设置数据源异常
            mediaPlayer.reset();
            mediaPlayer.setDataSource(str);
            // 设置准备完成监听器
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    startmusic();
                }
            });
            // 异步准备(网络资源推荐用这个,本地资源可改用prepare())
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(this, "音频加载失败", Toast.LENGTH_SHORT).show();
        }
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 销毁时释放MediaPlayer资源,防止内存泄漏
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    public class LocalBinder extends Binder {
        MyService getService() {
            return MyService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    public void startmusic() {
        if (!mediaPlayer.isPlaying()) {
            mediaPlayer.start();
        }
    }

    public void stopmusic() {
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
    }

    public boolean isplaying() {
        return mediaPlayer != null && mediaPlayer.isPlaying();
    }
}

启动Service代码优化

Intent intent = new Intent(getActivity(), MyService.class);
// 确保uri非空再传递
if (ur != null && !ur.isEmpty()) {
    intent.putExtra("uri", ur);
    getActivity().startService(intent);
} else {
    Toast.makeText(getActivity(), "音频地址为空", Toast.LENGTH_SHORT).show();
}
// 注:当前代码仅创建了ServiceConnection但未调用bindService,若不需要绑定可删除该部分代码;若需绑定,需调用:
// getActivity().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

额外注意事项

  • 播放网络音频需在AndroidManifest.xml添加权限:<uses-permission android:name="android.permission.INTERNET" />
  • Android 10+播放本地文件需申请存储权限或通过MediaStore获取合法URI
  • 建议通过绑定Service调用内部方法控制播放,减少重复启动Service导致的状态异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 23:04:52