java - 同时播放多个剪辑android studio - 使用线程?

标签 java android multithreading

我正在 android studio 中创建一个应用程序,我希望同时并排播放 10 个剪辑。我在三个剪辑中已经遇到了一些滞后问题,如果我最好使用线程,我会受伤吗?那怎么办?

任何提示都将非常感激

这是到目前为止我的代码。我知道它不是很有效,例如,我最好使用玩家对象的数组,但到目前为止我只是测试:

public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {

    private MediaPlayer mp1, mp2, mp3;
    private TextureView tv1, tv2, tv3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv1 = findViewById(R.id.textureView1);
        tv2 = findViewById(R.id.textureView2);
        tv3 = findViewById(R.id.textureView3);

        tv1.setSurfaceTextureListener(this);
        tv2.setSurfaceTextureListener(this);
        tv3.setSurfaceTextureListener(this);

    }


    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
        Surface surface = new Surface(surfaceTexture);
        mp1 = MediaPlayer.create(this, R.raw.a7);
        mp1.setSurface(surface);
//        mp1.prepareAsync(); //
        mp1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp1) {
                mp1.start();
            }
        });

        Surface surface2 = new Surface(surfaceTexture);
        mp2 = MediaPlayer.create(this, R.raw.a9);
        mp2.setSurface(surface2);
//        mp1.prepareAsync(); //
        mp2.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp2) {
                mp2.start();
            }
        });

        Surface surface3 = new Surface(surfaceTexture);
        mp3 = MediaPlayer.create(this, R.raw.a10);
        mp3.setSurface(surface3);
//        mp1.prepareAsync(); //
        mp3.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp3) {
                mp3.start();
            }
        });
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }

    @Override
    protected void onPause() {
        if (mp1 != null && mp1.isPlaying()) {
            mp1.pause();
        }
        super.onPause();
    }

    @Override
    protected void onResume() {
        if (mp1 != null) {
            mp1.start();
        }
        super.onResume();
    }

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

最佳答案

您应该在不同的非 UI 线程中播放媒体。像这样:-

public class MediaService extends Service  {
    private MediaPlayer mp1, mp2, mp3;
    private static final String ACTION_START = TAG + ".ACTION_START";
    private IBinder mBinder = new MyBinder();

    private MediaPlayer.OnPreparedListener mMediaPrepared = new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            Log.d(TAG, "MediaPlayer.onPrepared");
            onCommandPlay(mp);
        }
    };



    @Override
    public IBinder onBind(Intent intent) {
        Log.v(TAG, "onBind");
        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        m1 = MediaPlayer.create(this, R.raw.a1);
        m2 = MediaPlayer.create(this, R.raw.a2);
        m3 = MediaPlayer.create(this, R.raw.a9);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (m1 != null) m1 .release();
        if (m2 != null) m2 .release();
        if (m3 != null) m3 .release();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        final String action = intent.getAction();

        Log.d(TAG, "onStartCommand: " + intent.getAction());

        if (ACTION_START.equals(action)) {
            onCommandStart();
            return START_STICKY;
        }

        stopSelf();
        return Service.START_STICKY_COMPATIBILITY;
    }

    /**
     * Performs actions related to media player when Service onStartCommand method is called
     *
     */
    private void onCommandStart() {

        // Create Notifications with remote views
        mNotification = new NotificationCompat.Builder(this).setTicker("Media Service started...")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContent(collapsed)
                .setAutoCancel(false)
                .setOngoing(true)
                .build();

        startForeground(NOTIFICATION_ID, mNotification);
        startPlaying();
    }


    private void onCommandPlay(MediaPlayer mp) {
        try {
            mp.start();
        } catch (IllegalStateException e) {
            Log.e(TAG, "onCommandPlay", e);
        }
    }


    /**
     * Start playing the provided media item
     *
     */
    private void startPlaying() {
        mCurrent = item;
        try {
            mp1.reset();
            mp1.setOnPreparedListener(mMediaPrepared);
            mp2.reset();
            mp2.setOnPreparedListener(mMediaPrepared);
            mp3.reset();
            mp3.setOnPreparedListener(mMediaPrepared);
            AssetFileDescriptor afd1 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a9););
            AssetFileDescriptor afd2 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a10););
            AssetFileDescriptor afd3 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a8););
            mp1.setDataSource(afd1 .getFileDescriptor(), afd1 .getStartOffset(), afd1.getLength());
            mp2.setDataSource(afd2 .getFileDescriptor(), afd2 .getStartOffset(), afd2 .getLength());
            mp3.setDataSource(afd3 .getFileDescriptor(), afd3 .getStartOffset(), afd3 .getLength());
            mp1.prepareAsync();
            mp2.prepareAsync();
            mp3.prepareAsync();

        } catch (IOException e) {
            Log.e(TAG, "startPlaying", e);
        }
    }

    public class MyBinder extends Binder {
        public MediaService getService() {
            return MediaService.this;
        }
    }

}

然后从 Activity 启动服务,如下所示:

Intent intent = new Intent(context, MediaService.class);
intent.setAction(ACTION_START);
startServie(intent);

您还应该处理不同的媒体播放用例。你可以引用这个link了解更多。

关于java - 同时播放多个剪辑android studio - 使用线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56567107/

相关文章:

java - 如何响应 Actor 调用的结果?

java - 如何检查 session 对象是否包含特定的键/值条目

java - LWUIT - 在主题中使用数据导致 java.lang.OutOfMemoryError

android - 在 flutter 中使用 in_app_review 包?

java - 为什么并行流不使用ForkJoinPool的所有线程? [复制]

c++ - 在 C++ 中使用带有指针结构的 beginthread

c++ - 我想知道系统调用()被中断时到达的是哪个信号

java - 如何强制执行 Java API

android - Camera2 API - jpeg 捕获文件大小太大

android - offsetLeftAndRight() 究竟做了什么?