等待操作,直到创buildFragment的视图

我正在编程音乐播放器和音乐播放后台Service 。 当用户杀死承载3 FragmentsActivity ,然后再次重新开始Activity时,我从Service中发送包含关于当前播放歌曲的信息以及用户添加到他的会话中的歌曲列表的Broadcast

问题是,每次我想把最后的信息放入Fragments都不会发生,因为它们的创build时间太长,而Broadcast也不会像他们应该那样处理。

我如何让ServiceBroadcast等到碎片被创build之后才能正确处理?

以下是相关的代码片段:

 //When the activity binds to the service, refresh the fragments private ServiceConnection conn = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { LocalBinder binder = (LocalBinder) service; myService = binder.getService(); myService.setBound(true); if(myService.startedOnce) { myService.refreshFragments(); } myService.startedOnce = true; } } //This is the broadcast receiver of the Fragment //it receives the broadcast too soon, and I can't set the //Views so they are always empty. public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(MusicService.REFRESH_ALL)) { Song current = intent.getParcelableExtra("song"); setCurrentSong(current); } } 

Related of "等待操作,直到创buildFragment的视图"

最简单的事情就是坚持这些信息,直到Fragment准备好显示它为止。 使用Fragment的setArguments()方法将信息附加到Fragment中。

 @Override public void onReceive() { String action = intent.getAction(); if(action.equals(MusicService.REFRESH_ALL)) { // Creating a new Bundle so the Fragment can control its own object Bundle args = new Bundle(intent.getExtras()); Fragment fr = getUsingFragment(); fr.setArguments(fr); } } 

然后,在Fragment的onCreateView()只需从getArguments()参数, getArguments()用这些值构build视图。

 @Override public void onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Bundle args = getArguments(); if(args != null) { // code to set values if arguments are set } else { // code to set values if arguments are not set } } 

另一种方法是使用setter方法,其中片段本身将值放入setArguments()的Bundle中。 这样,当碎片视图被销毁并且必须被重新创build时,只要在设置可能事件的参数之前创build了视图,就可以更新视图。

注意:您只能在Fragment附加到Activity之前调用setArguments() 。 然而,你可以通过从getArguments()检索一个对它的引用来更新你通过setArguments传入的Bundle,然后简单地放入值。 所以不要从你的接收器调用setArguments() ,而应该这样做:

 public void setCurrentSong(Song extra) { Bundle args = getArguments(); args.putParcable(KEY_MAP, extra); if(/* Views are created */) { // update and invalidate the views } } 

我如何解决这个问题

当我使用媒体播放服务时,我想从服务中提取上次收听的歌曲,以便直接播放。 这是旧的逻辑,但我实际上build立了我的代码。 直到如此之久,我才碰上它。

这发生了

  • FragmentActivity被创build
  • Service开始并绑定
  • 同时Fragments是asynchronous创build的
  • 一旦Service启动,它发送一个Broadcast与最新的信息
  • 由于ServiceFragment创build都是asynchronous的,广播将从服务发送,但是由于Fragments中的BroadcastReceivers尚未初始化,因此不会收到Intent

我做了什么来解决它

我不知何故必须使用callback,确保

  • 该服务已创build并绑定到
  • 创build的片段和视图被设置

所以我使用了ServiceConnection ,更准确地说,是onServiceConnected()方法。 在那里,我得到了最后一首歌曲保存的偏好,然后发送BroadcastFragments收到它, Views适当地设置。 这也适用于方向的变化。

代码

 //This is the code in the FragmentActivity private ServiceConnection conn = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { LocalBinder binder = (LocalBinder) service; myService = binder.getService(); myService.setBound(true); if (myService.startedOnce) { myService.refreshFragments(); } else { sendLastSavedSong(); } myService.startedOnce = true; } public void onServiceDisconnected(ComponentName className) { myService.setBound(false); } }; 

你不能在片段中做些什么吗?

 Song current=null; public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(MusicService.REFRESH_ALL)) { current = intent.getParcelableExtra("song"); } } @Override public void onResume() { if(current!=null) setCurrentSong(current); super.onResume(); } 

我的解决scheme只是创build自己的callback接口。 在片段的onCreateView方法的最后,只要调用你的callback方法,它告诉你的主要活动是创build完成。

它为我工作,希望也可以帮助你。