无法使用 MediaPlayer 对象在 Android 中播放许多音频文件

Posted

技术标签:

【中文标题】无法使用 MediaPlayer 对象在 Android 中播放许多音频文件【英文标题】:Not able to play many audio files in Android using MediaPlayer objects 【发布时间】:2017-06-07 06:37:09 【问题描述】:

我有一个很大的列表视图。每个列表视图项都有一个播放按钮(图像)。单击该播放按钮时,它将播放一些小音频文件。

我创建了一个适配器来加载列表视图中的元素,并在播放时实现了 onClick 监听器。

当我启动应用程序时,它正在正确加载列表,但音频出现了一些问题。当我多次(比如 100 次)玩几个(比如 10-12)个项目时,它不会产生任何问题,一切都会顺利进行。

但如果我在列表中播放更多项目,例如 30-40 个项目。它停止为以后的项目加载音频文件。对于项目,它正在工作,它将继续工作,对于新项目,它不起作用。

    public class WordListAdapter extends BaseAdapter
    private ArrayList<Word> wordArrayList;
    private Activity activity;
    private static LayoutInflater inflater=null;
    MediaPlayer mp;

    public WordListAdapter(Activity activity, ArrayList<Word> wordArrayList) 
        this.activity = activity;
        this.wordArrayList = wordArrayList;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    

    @Override
    public int getCount() 
        return wordArrayList.size();
    

    @Override
    public Object getItem(int position) 
        return position;
    

    @Override
    public long getItemId(int position) 
        return position;
    

    @Override
    public View getView(final int position, final View convertView, final ViewGroup parent) 
        View view = convertView;
        if(convertView == null) 
            view = inflater.inflate(R.layout.item_word, null);
        

        TextView word1 = (TextView) view.findViewById(R.id.word1);
        TextView word2 = (TextView) view.findViewById(R.id.word2);
        ImageView imageWord = (ImageView) view.findViewById(R.id.imageWord);
        ImageView playWord = (ImageView) view.findViewById(R.id.playWord);

        word1.setText(wordArrayList.get(position).lang1);
        word2.setText(wordArrayList.get(position).lang2);

        if(wordArrayList.get(position).pic == 0) 
            imageWord.setVisibility(GONE);
        
        else 
            imageWord.setImageResource(wordArrayList.get(position).pic);
        

        playWord.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                mp = MediaPlayer.create(activity, wordArrayList.get(position).audio);
                mp.start();
            
        );

        return view;
    

我猜这个问题是因为我创建了太多的媒体播放器对象。

如何解决?

【问题讨论】:

您是在播放手机存储中的音频还是流媒体? 来自电话。 MediaPlayer.create(activity, wordArrayList.get(position).audio)我正在从资源中加载音频文件。 所有音频文件(大约 100 个)都在资源中。 【参考方案1】:

我曾经遇到过类似的问题,我所做的是使用服务播放媒体文件。我正在分享我所做的。创建如下服务

public class PlayMusicService extends Service
        implements MediaPlayer.OnCompletionListener,  MediaPlayer.OnErrorListener 

    private int audioResource;
    public static MediaPlayer player;


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 

        audioResource = intent.getIntExtra("musicResource",0);
        player = MediaPlayer.create(this, audioResource);
        player.setLooping(false);
        player.setVolume(100, 100);
        player.setOnCompletionListener(this);
        player.setOnErrorListener(this);
        player.start();
        return START_NOT_STICKY;
    

    @Override
    public void onDestroy() 
        super.onDestroy();
        player.stop();
        player.release();
    

    @Nullable
    @Override
    public IBinder onBind(Intent intent) 
        return null;
    


    @Override
    public void onCompletion(MediaPlayer mediaPlayer) 
        this.onDestroy();
    

    @Override
    public boolean onError(MediaPlayer mediaPlayer, int i, int i1) 
        return false;
    

然后像下面这样调用这个服务

        playWord.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
               Intent serviceIntent = new Intent(getActivity(),PlayMusicService.class);
               serviceIntent.putExtra("musicResource", wordArrayList.get(position).audio);
            
        );

让我知道它是否适合你。这里要记住的一件事是,您可能需要使用本地广播管理器来更改服务的视图。

【讨论】:

【参考方案2】:

MediaPlayer 使用系统编解码器,如果你不释放之前创建的 MediaPlayer,它最终会结束。所以尝试调用 mp.release()。例如,试试这个(只是我不确定它是否会起作用 - 自行发布):

playWord.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            mp = MediaPlayer.create(activity, wordArrayList.get(position).audio);
            mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() 
               @Override
               public void onCompletion(MediaPlayer mediaPlayer) 
                   mediaPlayer.release();
               
            );
            mp.start();
       
);

【讨论】:

以上是关于无法使用 MediaPlayer 对象在 Android 中播放许多音频文件的主要内容,如果未能解决你的问题,请参考以下文章

E/MediaPlayer: Should have subtitle controller already set

无法在 Nexus 5 中同时播放两个 MediaPlayer

无法使用 STREAM_VOICE_CALL 在 android java 中通过 MediaPlayer 播放音频

无法在对话框中使用 android MediaPlayer 播放声音?

MediaPlayer无法在Android Things Raspberry Pi 3上运行

android:使用单个 mediaplayer 对象播放音频文件并显示图像