0

我正在为平板电脑编写音乐播放器应用程序

活动可以被认为是3个部分

屏幕左侧有一个列表视图对象,用于浏览文件夹

屏幕中央有一个 listview 对象,其中包含在当前选定文件夹中找到的歌曲列表

屏幕右侧包含播放控件。

当用户导航到一个文件夹时,他们可以播放显示在中心栏中的文件列表。这工作 95% 完美。

当一首歌曲完成时,它会移动到中心列表视图中的下一个项目,并将其滚动到列表以将其放在顶部。

这可以完美运行几个小时,列表中的顶部项目是当前正在播放的歌曲。

但是,有时中间的列表与正在播放的歌曲完全不同步,几乎就像它已被重新填充一样。当应用程序在后台运行时,往往会发生这种情况。但是,这种情况非常罕见,以至于我无法找出原因可能是什么。

创建歌曲列表的代码在文件夹列表被触发后被调用。这会填充中心列,并将歌曲列表存储在内存中。音乐播放器根据记忆播放。但是,如果重新创建歌曲列表,那么内存中的列表将被破坏,并且肯定它们仍然会保持同步。

有人有什么建议吗?有什么吗?我确信这与应用程序重新回到焦点时创建/重新创建的活动有关,但为什么不是每次都发生这种情况?

编辑:有代码可以在 oncompletion 侦听器中滚动列表视图。如果应用程序不在屏幕上聚焦,虽然歌曲会在完成后移动到下一首歌曲,但列表视图是否能够滚动?如果不是,为什么这个问题是间歇性的?

创建活动时,我这样做:

mp.setOnCompletionListener(this);

这与以下代码有关:

 public void onCompletion(MediaPlayer mp) {

                // check for repeat is ON or OFF
                if(isRepeat){
                    // repeat is on play same song again
                    playSong(currentSongIndex);
                } 
                else{
                    // no repeat or shuffle ON - play next song
                    if(currentSongIndex < (songsList.size() - 1)){
                        playSong(currentSongIndex + 1);
                        currentSongIndex = currentSongIndex + 1;
                        //filelv.smoothScrollToPositionFromTop(currentSongIndex, 0);
                        if (android.os.Build.VERSION.SDK_INT >= 11)
                        {
                            filelv.smoothScrollToPositionFromTop(currentSongIndex, 0); 
                        }
                        else if (android.os.Build.VERSION.SDK_INT >= 8)
                        {
                            int firstVisible = filelv.getFirstVisiblePosition();
                            int lastVisible = filelv.getLastVisiblePosition();
                            if (currentSongIndex < firstVisible)
                                filelv.smoothScrollToPosition(currentSongIndex);
                            else
                                filelv.smoothScrollToPosition(currentSongIndex + lastVisible - firstVisible - 2);
                        }
                        else
                        {
                            filelv.setSelectionFromTop(currentSongIndex, 0);
                        } 


                    }else{
                        // play first song
                        playSong(0);
                        currentSongIndex = 0;
                        filelv = (ListView)getActivity().findViewById(R.id.FileList);
                        //filelv.smoothScrollToPositionFromTop(currentSongIndex, 0);
                        if (android.os.Build.VERSION.SDK_INT >= 11)
                        {
                            filelv.smoothScrollToPositionFromTop(currentSongIndex, 0); 
                        }
                        else if (android.os.Build.VERSION.SDK_INT >= 8)
                        {
                            int firstVisible = filelv.getFirstVisiblePosition();
                            int lastVisible = filelv.getLastVisiblePosition();
                            if (currentSongIndex < firstVisible)
                                filelv.smoothScrollToPosition(currentSongIndex);
                            else
                                filelv.smoothScrollToPosition(currentSongIndex + lastVisible - firstVisible - 2);
                        }
                        else
                        {
                            filelv.setSelectionFromTop(currentSongIndex, 0);
                        } 
                    }
                }
            }

发生的另一件事是我的应用程序尚未配置为作为服务运行。这可能是原因吗?

4

1 回答 1

1

此错误听起来像是上下文错误或线程问题。如果应用程序在后台并且 android 在不再需要时杀死了您的一个进程,您最终可能会遇到非常奇怪的行为。由于其他应用程序的时间和内存,这也将是间歇性的。

第一的

  • 发生这种情况时,log cat 中是否有任何奇怪的日志?

第二

然后尝试检查代码并寻找任何可疑之处。

  • 列表的创建是如何完成的。
  • 你有其他线程在运行吗?
  • 有没有人参考中间列表。
  • 有挂context objects在什么地方吗?

最后

如果您没有办法重现错误,则很难修复它,因此请尝试找到一种方法来强制它。比如:让应用程序在后台运行,然后打开很多其他应用程序,然后再回到你的音乐播放器。这可以有问题地完成,因此您不必自己做。

如果您能找到重现它的方法,那么只需开始消除代码,直到找到原因。

于 2012-08-25T18:18:44.697 回答