Xamarin Android如何防止Activity重启?解决MP3播放器横竖屏问题
解决Xamarin Android中Activity因屏幕旋转重启的问题
嘿,我看你已经尝试添加了configChanges配置,但还是碰到Activity重启、歌曲中断的问题对吧?其实只靠Manifest配置还不够,得配合代码处理配置变化,才能完全避免重启并保留播放状态。下面给你一步步来的解决方案:
1. 确认Activity的ConfigurationChanges配置正确
在Xamarin里,直接给Activity类加特性配置比手动改AndroidManifest.xml更方便,而且不容易出错:
[Activity( Label = "PlaylistActivity", // 必须包含这三个配置项,API13+屏幕旋转需要ScreenSize ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.KeyboardHidden, // 如果你要支持横竖屏切换,这里别设死竖屏,改成Sensor或者FullSensor ScreenOrientation = ScreenOrientation.Sensor )] public class PlaylistActivity : Activity { // 你的Activity代码 }
划重点:如果之前你把
ScreenOrientation设成了Portrait,一定要改过来,不然根本没法切换到横屏!
2. 重写OnConfigurationChanged方法处理布局切换
加了上面的配置后,系统就不会重启Activity了,而是会调用OnConfigurationChanged方法。我们要在这里手动更新布局,同时保存并恢复播放状态:
首先,在Activity里定义好播放相关的变量,方便保存状态:
private MediaPlayer _mediaPlayer; private int _currentPlayPosition; private bool _isPlaying; // 记录当前显示的是列表还是详情页 private bool _showingSongDetail; // UI控件引用 private LinearLayout _songListLayout; private LinearLayout _songDetailLayout;
然后在OnCreate里初始化这些变量和UI。接下来重写OnConfigurationChanged:
public override void OnConfigurationChanged(Configuration newConfig) { base.OnConfigurationChanged(newConfig); // 第一步:保存当前播放状态和进度 if (_mediaPlayer != null) { _currentPlayPosition = _mediaPlayer.CurrentPosition; _isPlaying = _mediaPlayer.IsPlaying; if (_isPlaying) _mediaPlayer.Pause(); // 先暂停,避免切换布局时卡顿 } // 第二步:保存当前UI状态(比如是否显示详情页) _showingSongDetail = _songDetailLayout.Visibility == ViewStates.Visible; // 第三步:加载对应方向的布局 // 如果横竖屏有单独的布局文件,就判断方向加载;如果是同一个布局自适应,直接调用SetContentView就行 if (newConfig.Orientation == Orientation.Landscape) SetContentView(Resource.Layout.PlaylistActivity_Landscape); else SetContentView(Resource.Layout.PlaylistActivity_Portrait); // 第四步:重新初始化UI控件引用 InitUiControls(); // 这个方法里重新FindViewById所有控件 // 第五步:恢复UI状态(比如回到之前显示的列表/详情页) if (_showingSongDetail) { _songListLayout.Visibility = ViewStates.Gone; _songDetailLayout.Visibility = ViewStates.Visible; } else { _songListLayout.Visibility = ViewStates.Visible; _songDetailLayout.Visibility = ViewStates.Gone; } // 第六步:恢复播放状态 if (_isPlaying && _mediaPlayer != null) { _mediaPlayer.SeekTo(_currentPlayPosition); _mediaPlayer.Start(); } }
3. 避坑提醒
- 别在OnConfigurationChanged里重新创建MediaPlayer:因为Activity没重启,
OnCreate只执行一次,播放组件应该在OnCreate里初始化好,切换布局时复用它,不然会导致歌曲从头播放。 - 不要遗漏ConfigChanges.ScreenSize:API 13及以上的系统,屏幕旋转会触发屏幕尺寸变化,必须把这个加上,不然系统还是会重启Activity。
- 测试时注意系统设置:有些手机的“自动旋转”开关要打开,不然不会触发方向变化。
额外优化(可选)
如果你的播放逻辑比较复杂,或者想让状态更稳定,可以用Android的ViewModel来保存播放状态和UI状态,这样即使系统因内存紧张回收了Activity,重新创建时也能恢复状态。不过针对你现在的屏幕旋转场景,上面的方法已经完全够用了。
内容的提问来源于stack exchange,提问作者Yousaf Haroon
相关产品推荐
相关产品推荐

