我需要在Android Studio的服务中运行MediaPlayer吗?

HelloCW

以下代码来自该项目

使用该MediaRecorder控件时可能需要很长时间,因此作者MediaRecorder在服务中运行,您可以看到代码B。

播放音频也许也是很长时间的操作,所以我认为作者应该MediaPlayer在服务中运行,但是为什么Code A不这样做?

代码A

public final class MediaPlayerHolder implements PlayerAdapter {

    public static final int PLAYBACK_POSITION_REFRESH_INTERVAL_MS = 1000;

    private MediaPlayer mMediaPlayer;
    
    @Override
    public void play() {
        if (mMediaPlayer != null && !mMediaPlayer.isPlaying()) {
            mMediaPlayer.start();
            if (mPlaybackInfoListener != null) {
                mPlaybackInfoListener.onStateChanged(PlaybackInfoListener.State.PLAYING);
            }
            startUpdatingCallbackWithPosition();
        }
    }
    ...
}

代码B

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

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

 
    public void startRecording(int duration) {
        setFileNameAndPath();
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        mRecorder.setOutputFile(mFilePath);

        mRecorder.setMaxDuration(duration); // set the max duration, after which the Service is stopped
        mRecorder.setAudioChannels(1);
        mRecorder.setAudioSamplingRate(44100);
        mRecorder.setAudioEncodingBitRate(192000);

       ...
    }

}
奥萨吉·阿格多(Osagui Aghedo)

使用服务的目的是让您的代码在后台运行,您可以执行不需要用户界面的操作,甚至可以使代码在活动的onDestoy()方法之外运行。即使关闭了应用程序的活动,音乐播放器也可以通过这种方式收听音乐。

有3种服务类型:

前台服务

后台服务

绑定服务

为什么在服务中使用代码B,而在服务中却没有?

从“绑定服务”概述中:

绑定服务是客户端服务器界面中的服务器。它允许组件(例如活动)绑定到服务,发送请求,接收响应以及执行进程间通信(IPC)。绑定服务通常仅在为另一个应用程序组件提供服务时才存在,并且不会无限期地在后台运行。

换句话说,它允许与其他应用程序或跨单独的进程进行通信。这就是作者使用服务的主要原因。它与性能无关。

关于效果:

代码不能说明性能。

服务概述中:

注意:服务在其托管过程的主线程中运行;除非另行指定,否则该服务不会创建自己的线程,也不会在单独的进程中运行。您应该在服务内的单独线程上运行任何阻止操作,以避免应用程序无响应(ANR)错误。

因此,仅使用服务并不能保证性能。在代码B中,我们有方法startRecording(),该方法将初始化MediaRecorder并为Recording设置一些参数。这并不意味着该方法将在服务启动后立即运行。作者使用了绑定服务,您可以通过以下方法判断:

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

这意味着绑定到它的任何组件(例如活动或另一个进程都可以调用其方法startRecording())。请检查绑定服务链接以获取更多信息。在项目中,可以从RecordViewModel.startRecording()调用它。

如果您担心性能。代码B应该在startRecording(int duration)内启动一个新线程。有很多方法可以做到这一点。这是一个:

public void startRecording(int duration) {

( new Thread( new Runnable() {

        @Override
        public void run() {
                

            setFileNameAndPath();
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            mRecorder.setOutputFile(mFilePath);

            mRecorder.setMaxDuration(duration); // set the max duration, after which the Service is stopped
            mRecorder.setAudioChannels(1);
            mRecorder.setAudioSamplingRate(44100);
            mRecorder.setAudioEncodingBitRate(192000);

       ...



        }

    }) ).start();


}

至于代码A,唯一发生的事情是对MediaPlayer.start()的调用,该调用已经在内部启动了一个新线程。

从MediaPlayer类的源代码:

public void start() throws IllegalStateException {
        //FIXME use lambda to pass startImpl to superclass
        final int delay = getStartDelayMs();
        if (delay == 0) {
            startImpl();
        } else {
            new Thread() {
                public void run() {
                    try {
                        Thread.sleep(delay);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    baseSetStartDelayMs(0);
                    try {
                        startImpl();
                    } catch (IllegalStateException e) {
                        // fail silently for a state exception when it is happening after
                        // a delayed start, as the player state could have changed between the
                        // call to start() and the execution of startImpl()
                    }
                }
            }.start();
        }
    }

如果代码A的性能令人担忧,则应在MediaPlayerHolder.loadMedia(String path)中使用单独的线程。

因此,回答您的问题。不,您不需要在服务中运行MediaPlayer。

问候

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Android Flutter:我需要在主体中设置“ SingleChildScrollView”吗?

我需要在 android 的 RecyclerView 中应用 SearchView

我只需要在 kotlin android 中打印 if 条件

我需要在Powershell中运行Maven文件吗?

我需要在C ++中对齐吗?

我们需要在Android 6.0中的运行时获得哪些权限

要在Android中启动新活动,我需要使用意图吗?

我们需要在Android中实现所有抽象方法吗?

我需要在Android中注销RegisterReceiver接收器吗

Android:我需要在Drawer上设置“汉堡图标” onClickListener吗?

我需要在C ++中取模

我需要在服务器上安装Composer吗?

为什么我们需要在Android应用中存储Goefence数据?

我是否需要在 iOS info.plist 和 Android 清单文件中添加“https”

我们是否需要在android中为sqlite表创建索引?

我需要在API控制台中注册我的android应用程序才能使用Geofences吗?

Android服务需要在后台运行,直到应用被终止

我如何需要在powershell中运行maven文件?

我需要在 onEdit 中运行 Google App 脚本

我需要在JavaScript中的“ throw”之后返回“ return”吗?

我需要在Java中实现继承的方法吗?

我需要在react函数中清除clearTimeout吗?

我需要在eventloop中包含所有函数吗?

我需要在Java目录中安装Glassfish吗?

我需要在Swift中设置C结构吗?

我需要在Laravel中验证数据用于查询吗?

我需要在java中拆分字符串吗?

我需要在每个项目目录中安装Express吗?

我需要在RabbitMQ中调用BasicPublish和BasicAck吗