tol*_*gap 9 android transactions android-service android-fragments
我正在编写音乐播放器,音乐在后台播放Service.当用户关闭Activity它承载3 Fragments,然后重新启动Activity一次,我送一个Broadcast从Service包含有关当前播放歌曲的信息,以及用户添加到其会话歌曲列表.
问题是,每当我想要将最后的信息设置为Fragments没有发生任何事情,因为他们的创建花费的时间太长,并且Broadcast不会像他们应该那样处理.
我怎样才能让片段创建Service或Broadcast等待,以便妥善处理?
以下是相关的代码段:
//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);
}
}
Run Code Online (Sandbox Code Playgroud)
Dee*_*eeV 14
最简单的事情就是保持信息直到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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在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
}
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用setter方法,其中Fragment本身将值放入Bundle for setArguments().这样,只要在Fragment的View被销毁并且必须重新创建时设置可能事件的参数,就可以在创建View时更新视图.
注意:您只能setArguments()在将片段附加到活动之前调用.但是,您可以通过setArguments从中检索对它的引用来更新传入的Bundle getArguments(),然后只需输入值.所以不要setArguments()从你的接收器呼叫,做这样的事情:
public void setCurrentSong(Song extra) {
Bundle args = getArguments();
args.putParcable(KEY_MAP, extra);
if(/* Views are created */) {
// update and invalidate the views
}
}
Run Code Online (Sandbox Code Playgroud)
当我使用媒体播放服务时,我想从该服务中调出上次收听的歌曲,以便我可以直接播放它。这是古老的逻辑,但我实际上是围绕它构建了我的代码。直到到目前为止我才遇到它。
FragmentActivity被建造Service开始并绑定到Fragments异步创建 getService,它会发出一个Broadcast带有最新信息的Service创建Fragment都是异步的,所以广播将从服务发送,但因为 甚至BroadcastReceivers还Fragments没有初始化,所以它们不会接收到Intent。我不得不使用回调来确保
所以我使用了,ServiceConnection准确地说,是onServiceConnected()方法。在那里,我获得了保存最后一首歌曲的首选项,然后发送Broadcast并接收了Fragments它并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);
}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12588 次 |
| 最近记录: |