我試圖構建一個簡單的MusicPlayer,並且在定位更改時遇到問題。我使用的是處理MediaPlayer的服務,因此它在後臺播放(即使該活動不在前臺),例如Google PlayMusic。該服務綁定到我獨特的單一MainActivity。問題是,當方向改變時,例如,它破壞了活動和服務(這是我猜測的預期行爲)。媒體播放器服務,ViewPagerAdapter上的方向更改
我不知道如何有效地處理生命週期。當方向改變時,它再次將服務綁定到活動。我的MainActivity使用ViewPager和FragmentPagerAdapter來處理選項卡並更新我對事件的看法。
當它再次創建活動(從方向更改)時,它再次綁定服務,執行「加載」,然後嘗試更新我的視圖,但由於某些原因頁面適配器中的片段爲空。我不知道爲什麼。理想情況下,我認爲我應該在應用程序開始時加載所有曲目。我應該在活動還是服務中這樣做(因爲它與服務有關)?
我不知道如何處理我的服務,活動和尋呼機適配器的生命週期。
我做了我的重現錯誤示例應用程序:
公共類MyActivity延伸活動{
private MediaPlayerService mediaPlayerService; private BroadcastReceiver broadcastReceiver; private MyPagerAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); ViewPager viewPager = (ViewPager) findViewById(R.id.pager); adapter = new MyPagerAdapter(getFragmentManager()); viewPager.setAdapter(adapter); broadcastReceiver = buildBroadcastReceiver(); Intent intent = new Intent(this, MediaPlayerService.class); bindService(intent, connection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { if (serviceBound) { unbindService(connection); serviceBound = false; } super.onDestroy(); } @Override protected void onResume() { registerReceiver(broadcastReceiver, new IntentFilter(MediaPlayerService.BROADCAST)); super.onResume(); } @Override protected void onPause() { unregisterReceiver(broadcastReceiver); super.onPause(); } private boolean serviceBound = false; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { mediaPlayerService = ((MediaPlayerServiceBinder) iBinder).getService(); serviceBound = true; mediaPlayerService.load(); } @Override public void onServiceDisconnected(ComponentName componentName) { serviceBound = false; } }; private BroadcastReceiver buildBroadcastReceiver() { return new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int action = intent.getIntExtra(MediaPlayerService.ACTION, 0); if (action == MediaPlayerService.ACTION_UPDATE_PLAYLIST) { List<String> cities = Arrays.asList("New York", "Toronto", "Tokyo"); //Data would be load from Database here ListFragment fragment = adapter.getFragment(); fragment.updatePlayList(cities); // Fragment is NULL on Orientation changes!? } } }; } }
。
公共類ListFragment延伸片段{
private ArrayAdapter<String> adapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View inflatedView = inflater.inflate(R.layout.playlist, container, false); adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, new ArrayList<String>()); ListView listView = (ListView) inflatedView.findViewById(R.id.list_view); listView.setAdapter(adapter); return inflatedView; } public void updatePlayList(List<String> items) { adapter.clear(); adapter.addAll(items); adapter.notifyDataSetChanged(); } }
。
public class MediaPlayerService extends Service { public static final String BROADCAST = "example.com.mediaplayersample.Broadcast"; public static final int ACTION_UPDATE_PLAYLIST = 3; public static final String ACTION = "ACTION"; private MediaPlayer mediaPlayer; public void load() { //Load... Intent intent = new Intent(MediaPlayerService.BROADCAST); intent.putExtra(MediaPlayerService.ACTION, ACTION_UPDATE_PLAYLIST); sendBroadcast(intent); } @Override public IBinder onBind(Intent intent) { return new MediaPlayerServiceBinder(); } public class MediaPlayerServiceBinder extends Binder { public MediaPlayerService getService() { return MediaPlayerService.this; } }
}
。
公共類MyPagerAdapter擴展FragmentPagerAdapter {
private ListFragment listFragment; public MyPagerAdapter(FragmentManager fragmentManager) { super(fragmentManager); }; @Override public Fragment getItem(int i) { if (i == 0) { if (listFragment == null) { listFragment = new ListFragment(); return listFragment; } } throw new IllegalStateException("Wrong index " + i); } @Override public int getCount() { return 1; } public ListFragment getFragment() { return listFragment; } }
編輯: 我理解的方式在清單文件中添加設置的建議:
<activity> android:name=.... android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" </activity>
但是,它似乎不被推薦。我計劃有幾種語言和不同的佈局,我不認爲刷新我所有的觀點是最好的方法。
我讀過這個「修復」是一個解決方法,但沒有建議。有很多原因會導致活動重新啓動,例如語言更改。我會有同樣的問題。我計劃處理幾種語言。 http://stackoverflow.com/questions/7818717/why-not-use-always-androidconfigchanges-keyboardhiddenorientation – MiniW 2014-09-03 16:10:27
@MiniW,好吧!你可以添加到android:configChanges =「locale」來處理語言change.i認爲這種追求可能會有所幫助:http://stackoverflow.com/questions/2644377/changing-locale-force-activity-to-reload-resources – AaoIi 2014-09-03 16:28:11
如果我有不同的佈局,我應該如何處理它?我想這是在onConfigurationChanged(),但我不知道如何有效地處理它。 – MiniW 2014-09-03 16:39:48