等待操作,直到创建Fragment的视图

时间:2012-11-10 12:24:20

标签: android transactions android-fragments android-service

我正在编制音乐播放器并且音乐在后台Service中播放。当用户杀死托管3 Activity的{​​{1}},然后再次重新启动Fragments时,我会从Activity发送Broadcast,其中包含有关当前播放的歌曲,以及用户添加到其会话中的歌曲列表。

问题是,每当我想将最后的信息设置为Service时,没有任何反应,因为它们的创建时间太长,并且Fragments没有得到应有的处理。

如何让BroadcastService等到片段创建,以便妥善处理?

以下是相关的代码段:

Broadcast

4 个答案:

答案 0 :(得分:14)

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

@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()中提取参数,然后使用值构建视图。

@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方法,其中Fragment本身将值放入setArguments()的Bundle中。这样,只要在Fragment的View被销毁并且必须重新创建时设置可能事件的参数,就可以在创建View时更新视图。

注意:您只能在将片段附加到活动之前调用setArguments()。但是,您可以通过从setArguments检索对getArguments()的引用来更新您通过setArguments()传入的Bundle,然后只需输入值即可。因此,不要从接收器中调用public void setCurrentSong(Song extra) { Bundle args = getArguments(); args.putParcable(KEY_MAP, extra); if(/* Views are created */) { // update and invalidate the views } } ,而是执行以下操作:

{{1}}

答案 1 :(得分:3)

我如何解决这个

当我使用服务进行媒体播放时,我想从服务中调出最后收听的歌曲,以便我可以直接播放。这是旧逻辑,但我实际上围绕它构建了我的代码。直到那时我碰到了它。

发生了这种情况

  • FragmentActivity已创建
  • Service开始并绑定到
  • 同时Fragments以异步方式创建
  • Service启动后,会立即发送Broadcast最新信息
  • 由于ServiceFragment创建都是异步的,广播将从服务发送,但因为BroadcastReceivers中的Fragments不是即使已初始化,他们也不会收到Intent

我做了什么来解决它

我不得不使用确保

的回调
  • 服务已创建并绑定到
  • 创建的片段和视图已设置

所以我使用了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);
    }
};

答案 2 :(得分:0)

你不能在像

这样的片段中做点什么
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();
}

答案 3 :(得分:0)

我的解决方案就是创建自己的回调接口。在ur片段的onCreateView方法的最后,只需调用你的回调方法,它告诉你主要活动是否完成了创作。

它对我有用,希望也能帮到你。