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

Android Studio开发音乐应用:切换下一曲时偶发运行时崩溃

Hey there! Let's figure out why your music app crashes randomly when tapping the next track button. From what you've shared, everything works most of the time—so this is almost certainly an edge case you haven't accounted for yet. Let's break down the most likely causes and how to fix them:

1. 数组/列表越界异常(最常见)

This is the #1 culprit for random next-track crashes. When you tap "next," you might not be checking if you're already at the last song in your list. For example, if your current index is songList.size() - 1, incrementing it to songList.size() will throw an IndexOutOfBoundsException when you try to access that position.

Fix it with a quick boundary check:

if (currentSongIndex < songList.size() - 1) {
    currentSongIndex++;
    playSelectedSong(songList.get(currentSongIndex));
} else {
    // Option 1: Loop back to the first song
    currentSongIndex = 0;
    playSelectedSong(songList.get(currentSongIndex));
    // Option 2: Disable the button or show a toast saying "No more songs"
    // Toast.makeText(context, "Last song reached!", Toast.LENGTH_SHORT).show();
}

2. 空指针异常(NullPointerException)

Sometimes your songList might get cleared unexpectedly, or a song object could be null (e.g., if the SD card is unmounted mid-playback, or a background list refresh isn't finished yet). Trying to access a null song's path or metadata will crash the app.

Fixes & checks to add:

  • Validate the list and song object before playing:
    if (songList != null && !songList.isEmpty()) {
        if (currentSongIndex >= 0 && currentSongIndex < songList.size()) {
            Song targetSong = songList.get(currentSongIndex);
            if (targetSong != null && targetSong.getFilePath() != null) {
                // Proceed with playback
                initiatePlayback(targetSong.getFilePath());
            } else {
                // Skip this invalid song and move to the next valid one
                skipToNextValidSong();
            }
        }
    }
    
  • Use a thread-safe collection like CopyOnWriteArrayList for your song list if it's being updated by background threads—this prevents concurrent modification issues.

3. MediaPlayer State Mismanagement

Your MediaPlayer instance might be in an invalid state (e.g., released but still being called) when switching tracks. Forgetting to properly stop/release the old player before initializing a new one can cause random runtime exceptions.

Clean up the player properly before switching:

if (mediaPlayer != null) {
    if (mediaPlayer.isPlaying()) {
        mediaPlayer.stop();
    }
    mediaPlayer.release();
    mediaPlayer = null;
}

// Initialize new player for the next song
try {
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setDataSource(context, Uri.parse(nextSongPath));
    mediaPlayer.prepareAsync(); // Use async to avoid blocking the main thread
    mediaPlayer.setOnPreparedListener(mp -> mp.start());
} catch (IOException e) {
    e.printStackTrace();
    // Handle playback failure (e.g., file not found)
}

4. Unexpected Permission Revocation

Even though your app can read the SD card normally, if the user revokes storage permission while the app is running, accessing song files will throw a SecurityException and crash the app.

Add a permission check before accessing songs:

if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {
    // Request permission again or show a prompt to the user
    ActivityCompat.requestPermissions(activity, 
            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
            STORAGE_PERMISSION_REQUEST_CODE);
    return;
}

Next Steps to Diagnose

  • Dig into the crash log: Look for the exact exception type and the line of code it points to—this will tell you exactly where the problem is. For example, if it's an IndexOutOfBoundsException at MusicPlayerActivity.java:145, go straight to that line to check your index logic.
  • Add debug logs: Print the current index and list size when the next button is tapped:
    Log.d("MusicPlayerDebug", "Current index: " + currentSongIndex + " | List size: " + songList.size());
    
    This will help you see what values triggered the crash next time it happens.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:32:27