MediaPlayer播放音乐(本地/在线),java.lang.IllegalStateException报错处理

转载请注明出处MediaPlayer播放音乐(本地/在线)_Mr_Leixiansheng的博客-CSDN博客

步骤:

1、布局文件设置播放、暂停、停止3个按钮

2、主程序中新建MedioPlayer对象,在按键监听中实现音乐的播放、暂停、停止

3、声明权限

注意事项:

1、一定要声明权限

2、在开始播放前必须要先prepare();

否则会出现(-38,0)错误

代码如下:

1、布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/pause"
        android:text="暂停"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/play"
        android:text="开始"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/stop"
        android:text="停止"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />

</LinearLayout>

2、功能实现

package com.example.administrator.player;

import android.media.MediaPlayer;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;


import java.io.File;
import java.io.IOException;


public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button play;
    private Button pause;
    private Button stop;
    private MediaPlayer mediaPlayer = new MediaPlayer();
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        play = (Button) findViewById(R.id.play);
        pause = (Button) findViewById(R.id.pause);
        stop = (Button) findViewById(R.id.stop);

        play.setOnClickListener(this);
        pause.setOnClickListener(this);
        stop.setOnClickListener(this);
        //初始化播放器
        initPlayer();

    }

    private void initPlayer() {
        try {
            File file = new File(Environment.getExternalStorageDirectory(), "music.mp3");
            mediaPlayer.reset();
            mediaPlayer.setDataSource(file.getPath());
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.play:
                if (!mediaPlayer.isPlaying()) {
                    mediaPlayer.start(); // 开始播放
                }
                break;
            case R.id.pause:
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.pause(); // 暂停播放
                }
                break;
            case R.id.stop:
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.reset(); // 停止播放
                    initPlayer();
                }
                break;
            default:
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }
    }

}

3、注册声明

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.administrator.player">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Kotlin写法:(播放在线音乐)

package com.leixiansheng.kotlintest

import android.media.MediaPlayer
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity(),View.OnClickListener{

    private var player: MediaPlayer = MediaPlayer()
    private val url = "http://abv.cn/music/光辉岁月.mp3"        //网络音乐播放地址


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initPlayer()

        initEvent()
    }

    private fun initPlayer() {
        player.setDataSource(url)
        player.prepare()
    }

    private fun initEvent() {
        play.setOnClickListener(this)
        pause.setOnClickListener(this)
        stop.setOnClickListener(this)
    }

    override fun onClick(v: View) {
        when (v.id) {
            play.id -> if (!player.isPlaying) player.start()

            pause.id -> if (player.isPlaying) player.pause()

            stop.id -> {
                if (player.isPlaying){
                    player.reset()
                    initPlayer()
                }
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        player.stop()
        player.release()
    }
}

但是在第二次调用mediaPlayer.setDataSource() 时报错如下:

java.lang.IllegalStateException
        at android.media.MediaPlayer._setDataSource(Native Method)
        at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1337)

原因:资源没释放干净。大部分原因是因为java里面的MediaRecorder /MediaPlayer 对象和native的对象不一致导致的。在java中释放掉MediaRecorder /MediaPlayer的对象时,释放的是jni的对象,而java中只释放了栈中的内容,而堆中的内容没有释放。说到底就是没释放干净,导致出现对象不一致。

处理方法

在 mediaPlayer.setDataSource(path); 之前加一句:

mediaPlayer.reset();即可

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值