我是Android開發新手。我正在構建一個簡單的Android應用程序,用於分析accelerometer sensor
數據,並用MediaPlayer
播放聲音。對於SensorEventListener
實現代碼:關鍵部分無法在onSensorChanged()
class AccelListener implements SensorEventListener {
boolean firstUpdate = true;
volatile boolean stopped = true;
private MediaPlayer mplayer;
//some variables to store calculations
public AccelListener(MediaPlayer mediaplayer) {
mplayer = mediaplayer;
mplayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
if (mplayer == mp) {
synchronized (AccelListener.this) {
stopped = true;
}
Log.d("MediaPlayer Callback", "stopped=" + stopped);
}
}
});
}
public void onSensorChanged(SensorEvent event) {
updateAccel(event.values);
if (isAccelChanged()) {
Log.d("Accel Listener", "stopped_before=" + stopped);
synchronized (this) {
if (stopped) {
stopped = false;
firstUpdate = true;
mplayer.start();
Log.d("Accel Listener", "stopped_after=" + stopped);
}
}
}
}
}
的問題是,當我啓動應用程序,並開始搖晃手機,聲音在同一時刻扮演了好幾次。音頻文件長約3-4秒,所以它沒有辦法播放到最後,然後對下一次搖動做出反應。
logcat的示出了以下內容:在onSensorChanged()
和onCompletion()
08-12 22:16:24.693: D/Accel Listener(5382): stopped_before=true
08-12 22:16:24.693: D/Accel Listener(5382): stopped_after=false
08-12 22:16:24.693: D/Accel Listener(5382): stopped_before=true
08-12 22:16:24.703: D/Accel Listener(5382): stopped_after=false
08-12 22:16:28.777: D/MediaPlayer Callback(5382): stopped=true
08-12 22:16:28.777: D/MediaPlayer Callback(5382): stopped=true
關鍵段被鎖定相同的對象(I使只有一個節目的AccelListener
實例)上,所以應該沒有並行訪問stopped
。
此外,這個變量被聲明爲volatile
,所以任何進入關鍵的人都應該有一個新的最新值。但似乎兩個不同線程實際上同時進入臨界區域,兩者都具有相同的標誌值。這怎麼可能發生,我錯在哪裏?
P.S. here的傢伙似乎也有同樣的問題,但他的案例(例如在單獨的對象上同步或使用同一個MediaPlayer
實例)的解決方案都不適用於我。
我推測,如果**(!停止){回報;} ** **時停止=假**只會中止執行梅託德,使** mplayer.start()**無法訪問。刪除同步並沒有改變任何東西,也沒有將** mplayer.start()**移動到臨界區。 – 2012-08-12 19:43:02
Ahh ..是正確的!應該無法訪問。並且再次如此,這意味着從「如果」到「Log.d」有人正在改變停止的值。很奇怪。 你能分享你使用的最終代碼嗎? – 2012-08-12 19:52:41
更新的代碼。儘管我留下了'同步'塊,因爲沒有它們的版本是我開始使用的那個版本,它並沒有幫助。 – 2012-08-12 20:16:06