Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 异步播放mp3。播放但随后崩溃线程_Android_Multithreading_Audio - Fatal编程技术网

Android 异步播放mp3。播放但随后崩溃线程

Android 异步播放mp3。播放但随后崩溃线程,android,multithreading,audio,Android,Multithreading,Audio,我需要在我的Android应用程序中异步播放声音 这是一个短的嘟嘟声mp3(1秒长),但我仍然需要它不阻止当前的线程在所有。。。重要的是,线程正忙于寻找新的蓝牙数据 需要播放声音的线程是意图服务 我在主线程中函数调用的开头有以下代码。。。这是为了准备MP3,以便稍后播放。我希望我可以像这样初始化它,并在需要时调用某种“播放声音”方法 我的理解是,通过使用OnPreparedListener,MediaPlayer将为我处理以不同方式播放声音的所有细节 MediaPlayer ob

我需要在我的Android应用程序中异步播放声音

这是一个短的嘟嘟声mp3(1秒长),但我仍然需要它不阻止当前的线程在所有。。。重要的是,线程正忙于寻找新的蓝牙数据

需要播放声音的线程是意图服务

我在主线程中函数调用的开头有以下代码。。。这是为了准备MP3,以便稍后播放。我希望我可以像这样初始化它,并在需要时调用某种“播放声音”方法

我的理解是,通过使用OnPreparedListener,MediaPlayer将为我处理以不同方式播放声音的所有细节

        MediaPlayer objMediaPlayer = MediaPlayer.create(getApplicationContext(),R.raw.beeplow);
        objMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mp.start();
            }
        });
上述方法似乎有效,没有崩溃

然后,稍后我想播放声音:

                    //play sound...
                    objMediaPlayer.prepareAsync();
这确实播放了声音。。。但是,epic失败,线程崩溃

我做错了什么

以下是LogCat信息(如果有帮助的话):

08-19 14:17:51.790  15995-16037/com.example.owner.soundtest V/MediaPlayer﹕ setVideoSurfaceTexture
08-19 14:17:51.790  15995-16037/com.example.owner.soundtest V/MediaPlayer﹕ prepareAsync
08-19 14:17:51.790  15995-16037/com.example.owner.soundtest E/MediaPlayer﹕ prepareAsync called in state 8
08-19 14:17:51.800  15995-16037/com.example.owner.soundtest I/MediaPlayer﹕ Info (973,0)
08-19 14:17:51.800  15995-16037/com.example.owner.soundtest I/MediaPlayer﹕ Don't send intent. msg.arg1 = 0, msg.arg2 = 0
08-19 14:17:51.800  15995-16037/com.example.owner.soundtest V/MediaPlayer-JNI﹕ start
08-19 14:17:51.800  15995-16037/com.example.owner.soundtest V/MediaPlayer﹕ start
08-19 14:17:52.260  15995-16008/com.example.owner.soundtest V/MediaPlayer﹕ message received msg=2, ext1=0, ext2=0
08-19 14:17:52.260  15995-16008/com.example.owner.soundtest V/MediaPlayer﹕ playback complete
08-19 14:17:52.260  15995-16008/com.example.owner.soundtest V/MediaPlayer﹕ callback application
08-19 14:17:52.270  15995-16008/com.example.owner.soundtest W/MessageQueue﹕ Handler (android.media.MediaPlayer$EventHandler) {42fb2890} sending message to a Handler on a dead thread
    java.lang.RuntimeException: Handler (android.media.MediaPlayer$EventHandler) {42fb2890} sending message to a Handler on a dead thread
            at android.os.MessageQueue.enqueueMessage(MessageQueue.java:311)
            at android.os.Handler.enqueueMessage(Handler.java:623)
            at android.os.Handler.sendMessageAtTime(Handler.java:592)
            at android.os.Handler.sendMessageDelayed(Handler.java:563)
            at android.os.Handler.sendMessage(Handler.java:500)
            at android.media.MediaPlayer.postEventFromNative(MediaPlayer.java:2776)
            at dalvik.system.NativeStart.run(Native Method)
08-19 14:17:52.270  15995-16008/com.example.owner.soundtest V/MediaPlayer﹕ back from callback
进一步信息

这是否与我正在使用的“getApplicationContext()”有关。。。这是创建对象的正确方法吗?我对Android还是一个新手,尽管我花了很多时间阅读和研究,所有这些背景和意图的东西都还没有被理解

上面所有的代码都是在一个意图服务的线程中调用的。。。因此,它已经与UI完全断开连接

黑客补丁

通过在我的线程开始时执行此操作:

        MediaPlayer objMediaPlayer = MediaPlayer.create(getBaseContext(),R.raw.beeplow);
然后,每次我想播放短嘟嘟声时,我都会这样做:

                    if(objMediaPlayer.isPlaying()){
                        objMediaPlayer.stop();
                        objMediaPlayer.release();
                        objMediaPlayer = MediaPlayer.create(getBaseContext(),R.raw.beeplow);
                    }
                    objMediaPlayer.start();
似乎有效。糟糕的代码和糟糕的形式,但是的,我只想播放一个$**的声音,而不需要花费数小时和数百行代码!克雷西

正确修复???

下面的方法似乎有效。希望这是正确的方法。。。当我看到其他解决方案时,它们似乎是一个服务中隐藏的50多行代码等等。我喜欢下面这个。。。如果这是一个正确的方式来发射线程,我会在任何地方这样做

                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            MediaPlayer objMediaPlayer = MediaPlayer.create(getBaseContext(),R.raw.beeplow);
                            objMediaPlayer.start();
                        }
                    }, "PlayBeepLow").start();
向死线程上的处理程序发送消息

在里面做是不安全的,因为当它用完工作时会自动停止

上面所有的代码都是在一个意图服务的线程中调用的。。。 因此,它已经与UI完全断开连接

处理完所有请求后,会自动停止

我建议在一个时间内做,并处理自己的线程

@Override
public int onStartCommand(final Intent intent, int flags, final int startId) 
{
    new Thread(new Runnable() {
        @Override
        public void run() {
            // handle your own media playing here...
        }
    }, "MplayerService").start();

    ...
}
如果你想让用户控制你的媒体播放器

我建议绑定一个服务就可以了

文档中的更多信息:

服务
服务是一种应用程序组件,表示应用程序希望在不与用户交互的情况下执行更长时间的运行操作,或者为其他应用程序提供功能

IntentService
IntentService是按需处理异步请求(表示为intent)的服务的基类。客户端通过startService(Intent)调用发送请求;该服务根据需要启动,使用工作线程依次处理每个意图,并在工作结束时自行停止


希望这能有所帮助。

Intent服务将永远运行。。。在安卓决定杀了它之前。。。但是是的,它应该无休止地收集蓝牙数据。在手机锁定的情况下测试了5小时,没有问题。只要试着在线死的时候播放声音。我将尝试使用你的新线程(…代码来触发声音。它只是意味着当新数据进来时发出嘟嘟声,没有什么花哨的,没有用户界面。谢谢:-)线程解决方案工作正常。。。我不确定我做得是否正确,但它很有效。很高兴它能帮上忙,我在我的服务中也做了一个线程,它在不到10秒内接收100多条消息,并将消息用作需要ui线程的地图中的数据,这就是为什么我需要一个长时间运行的服务,创建一个线程并创建广播接收器来执行msending等。它解决了我在拥有ANRs时的问题。我很高兴它对你也有用