我有一个应用程序,它有一个活动,可以在一种自定义导航抽屉设计中托管多个片段。其中两个片段依赖于服务来返回它们以显示json信息。 我希望能够在我的启动画面上启动服务,以加载我需要的数据,然后将json异步传递给这些片段。
我是Android和编程的新手,所以请原谅我,如果我的行为不明,但我首先尝试将片段注册为接收器,然后简单地广播包含json信息的意图。这似乎不起作用,因为当服务广播意图并错过意图时,有时片段不会运行。
然后我决定使用粘性意图,但这导致陈旧的信息,更不用说继承安全问题了。
让服务在启动应用程序时执行后台网络请求,然后由任何活动或片段显示返回的信息的最佳方法是什么?
答案 0 :(得分:4)
相信我,我在大型企业项目中尝试了很多第三方方法(服务总线,观察......),结果发现原生Android机制是最快且最强大的,因为它们利用了框架和#39;的好处。
这就是为什么我建议使用LocalBroadcastManager和BroadcastReceiver。在您的活动中(或您的can事件为每个片段执行此操作!)在onStart
中注册,并在onPause
注销专用接收器。
使用服务中的LocalBroadcastManager与所有潜在订阅者进行通信。
示例:
public class YourActivity extends Activity{
private BroadcastReceiver receiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
//...do the stuff you need to do depending on the received broadcas
}
};
private IntentFilter filter = new IntentFilter(UploadService.INTENT_ACTION_UPLOAD);
protected onStart(){
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
}
protected onPause(){
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
}
public class UploadService extends IntentService{
public static final String INTENT_ACTION_UPLOAD = "com.your.package.INTENT_ACTION_UPLOAD";
public onHandleIntent(){
//upload
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(INTENT_ACTION_UPLOAD));
}
}
在BroadcastReceiver的onReceive
中,您可以根据收到的广播做您需要做的事情。如果您需要区分更多,可以使用不同的操作或附加功能,例如在您的服务中:
...send(new Intent(INTENT_ACTION_SOMETHING_ELSE));
或
send(new Intent(...).putExtra(WAS_SUCCESSFUL, false));
send(new Intent(...).putExtra(DOWNLOADED_CONTENT, downloadedStuff);
答案 1 :(得分:1)
使用事件总线而不是广播意图,例如Green Robot EventBus(也支持粘性广播)
答案 2 :(得分:1)
您不仅可以从启动画面调用startService(),还可以从片段getActivity().startService()
调用。
从Service(而不是从IntentService)派生您的服务。在onStartCommand()
中,它将从网络读取数据,然后广播结果。如果结果已经加载,服务可以简单地广播结果。
当您从启动画面调用startService()
时,服务会从网络加载数据并将其广播到此刻显示的片段。创建新片段时,它再次调用startService()
并且服务广播缓存数据。
另一种方法是bindService。您的片段可以绑定到onCreate()
上的服务,并在onDestroy()
上取消绑定。在这种情况下,片段可以直接调用服务的方法。