首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关键部分在onSensorChanged()中不起作用

关键部分在onSensorChanged()中不起作用
EN

Stack Overflow用户
提问于 2012-08-12 18:51:57
回答 2查看 677关注 0票数 1

我是Android开发的新手。我正在构建一个简单的安卓应用程序,它分析accelerometer sensor数据并使用MediaPlayer播放声音。SensorEventListener实现代码:

代码语言:javascript
复制
    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显示如下:

代码语言:javascript
复制
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

onSensorChanged()onCompletion()中的关键部分被锁定在同一个对象上(我在程序中只创建了一个AccelListener实例),因此不应该有对stopped的并行访问。

此外,这个变量被声明为volatile,所以任何输入临界值的人都应该有一个新的、最新的值。但是,看起来两个不同的线程实际上同时进入了关键部分,它们都具有相同的标志值。这怎么会发生,我哪里错了?

这里上的那个家伙似乎也有同样的问题,但是对于他的情况,没有一个解决方案(比如在不同的对象上同步或者使用相同的MediaPlayer实例)对我起作用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-13 16:04:22

问题解决了。我没有注销AccelListener,而且调试器似乎没有正确地停止运行程序的版本。每个连续的Run命令都只是启动了main活动,它实例化了AccelListener,注册了它,等等。添加以下代码修复了整个过程:

代码语言:javascript
复制
@Override
protected void onPause() {
    super.onPause();
    sensMgr.unregisterListener(grListener);
}

@Override
protected void onResume() {
    super.onResume();
    sensMgr.registerListener(grListener,
            sensMgr.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
            SensorManager.SENSOR_DELAY_GAME);
}
票数 0
EN

Stack Overflow用户

发布于 2012-08-12 19:13:05

假设您在"isAccelChanged() if“中输入,则始终在"onSensorChanged”内启动播放机中的声音,而不考虑stopped的值(它不在if中,也不在同步块之外)。

如果你确信你只有一个实例,你可以去掉“同步”。

检查一下,然后回复。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11924873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档