ViTess / Android-FmlPlayer

44 stars 8 forks source link

ANR问题 #3

Open tangmingscau opened 7 years ago

tangmingscau commented 7 years ago

您好。目前发现一个播放问题。播放网络音乐,这时候网络比较差,歌曲没有准备好,这时候我连续点击2次下一曲(下一曲是本地音乐)。目前会发生ANR,目前定位到问题是卡在fmlplayer中的方法stop()中public boolean stop() { Log.d(TAG, "stop"); synchronized (this) { // 由于设置了不重放,stop和pause一样从暂停处开始 // 所以这里要做处理 Log.d(TAG, "synchronized stop"); BASS.BASS_ChannelStop(mHandle); seekTo(0d); traces.txt

        Log.d(TAG, "stop complete");
        return (printError("Stop") == seekTo(0d));
    }
}

没办法执行进去synchronized(this)里面的代码。我想问下您有没有好的解决办法思路

ViTess commented 7 years ago

trace文件能提供一下吗?

ViTess commented 7 years ago

@tangmingscau 是这样的,调用网络播放时使用的BASS.BASS_StreamCreateURL这个方法会阻塞线程,该方法在prepare()里被调用,prepare()里的代码都用synchronized标注代码块了,所以导致这个问题,你试试把synchronized去掉看看

tangmingscau commented 7 years ago

traces.txt

这个traces.txt文件,对于你所说的取消掉synchronized的做法,如果单单取消一个stop里面的synchronized是不起作用的。我尝试下取消全部的synchronized,看下有没有问题

tangmingscau commented 7 years ago

全部取消synchronized,网络歌曲没有准备好,可以直接进入下一曲。但是这容易造成其他的crash,就是拼命点击下一曲,程序无缘无故就crash了,之前不会的。

ViTess commented 7 years ago

建议把网络歌曲的调用部分提取出来,或者单独再开一个FmlPlayer处理网络歌曲。 由于BASS.BASS_StreamCreateURL阻塞线程,阻塞后再调用stop之类的一样会阻塞。我想应该是作者在jni层加了锁。

全部取消synchronized不可取。由于我在内部维护一个单线程池来处理BASS.BASS_StreamCreateURL,但是其后的操作(如stop)没有为其加入线程,在这个思路上你可以试试将其加入线程池或作其他操作。

tangmingscau commented 7 years ago

感谢您的解惑。按照您新的建议,对我这边代码改动很大。目前手头上还有其他事情,没那么多时间进行这种大改动。我过几天抽出时间来专门按照您的思路来写下代码。到时候再更新下问题状态。

tangmingscau commented 7 years ago

尝试将FmlPlayer中的方法prepare()中的synchronized (this)去掉,歌曲没准备好下一曲也可以执行,不会crash,但是拼命点击下一曲,偶发性会crash,定位到问题是so库挂了。但是这样crash的情况已经降到很低了。为什么拼命点击下一曲会crash,这个有思路吗?