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

Android MediaPlayer错误(1,-19)规避方案及资源释放疑问

Hey there! Let's tackle this E/MediaPlayer: error (1, -19) issue you're facing. I've dealt with similar MediaPlayer headaches before, so let's break this down step by step based on your scenario.

First, let's clarify what that error means: Error (1,-19) almost always stems from invalid MediaPlayer state management—usually trying to load a new media source without properly cleaning up the old instance, or reusing an instance that's already been released. Since you're spawning new media files on every click (even if the previous one is still playing), not handling the old MediaPlayer correctly is the root cause here.

Here's your actionable fix plan:

1. Reuse a single MediaPlayer instance (don't create new ones every click)

Stop instantiating a new MediaPlayer in each onClick()—instead, declare a global instance in your Activity/Fragment. This way, you can control its state properly every time the user clicks:

package com.example.okunato.chance;

// ... other imports ...

public class YourActivity extends AppCompatActivity implements View.OnClickListener {
    // Global MediaPlayer instance
    private MediaPlayer mp3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout);
        // Set click listener to your button/view
        findViewById(R.id.your_clickable_view).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // Generate your random media source here (replace with your actual logic)
        Uri randomMediaUri = getRandomMediaUri();

        // Handle existing MediaPlayer instance first
        if (mp3 != null) {
            if (mp3.isPlaying()) {
                mp3.stop(); // Stop current playback if ongoing
            }
            mp3.reset(); // Reset to idle state to load new source
            try {
                mp3.setDataSource(this, randomMediaUri);
                mp3.prepare(); // Prepare new source
                mp3.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            // First click: create instance and start playback
            mp3 = MediaPlayer.create(this, randomMediaUri);
            mp3.start();
        }
    }

    // Helper method for your random media logic
    private Uri getRandomMediaUri() {
        // Your existing random media generation code here
        return ...;
    }
}

Note: MediaPlayer.create() automatically calls prepare(), so you don't need to do that for the first instance. For reset instances, you must call prepare() (or prepareAsync() for large files) before starting.

2. Properly release resources (don't just set mp3 = null randomly)

Setting mp3 = null without releasing first leaves the old instance holding system resources, which causes the error you're seeing. The correct place to clean up is when your component is destroyed:

@Override
protected void onDestroy() {
    super.onDestroy();
    if (mp3 != null) {
        if (mp3.isPlaying()) {
            mp3.stop();
        }
        mp3.release(); // Free all system resources tied to this instance
        mp3 = null; // Nullify to avoid memory leaks
    }
}

Never set mp3 = null in onClick() unless you're done using it entirely—this breaks state management and leads to orphaned instances.

3. Optional: Add a guard against rapid clicks (reduces state chaos)

Even if you don't care about audio overlap, rapid clicks can push MediaPlayer into invalid states. A simple flag can prevent this:

private boolean isMediaProcessing = false;

@Override
public void onClick(View v) {
    if (isMediaProcessing) return;
    isMediaProcessing = true;

    // ... existing MediaPlayer logic ...

    // Reset the flag when playback finishes
    mp3.setOnCompletionListener(mediaPlayer -> isMediaProcessing = false);
}

4. Avoid common pitfalls

  • Don't call release() multiple times: Always check mp3 != null before any operation to avoid exceptions.
  • For large media files: Use prepareAsync() instead of prepare() to avoid blocking the main thread (ANR errors):
    mp3.reset();
    mp3.setDataSource(this, randomMediaUri);
    mp3.prepareAsync();
    mp3.setOnPreparedListener(mediaPlayer -> {
        mediaPlayer.start();
        isMediaProcessing = false;
    });
    

Quick recap

The core fix is reusing one MediaPlayer instance, resetting its state on each click, and properly releasing it when your activity/fragment is destroyed. Your earlier mp3 = null was misplaced—only do that after calling release() in onDestroy().

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:27:52