【问题标题】:Android service communicating with multiple fragmentsAndroid 服务与多个 Fragment 通信
【发布时间】:2026-02-21 19:10:01
【问题描述】:

我有一个应用程序,它有一个活动,该活动在一种自定义导航抽屉设计中托管多个片段。其中两个片段依赖于服务来返回要显示的 json 信息。 我希望能够在初始屏幕上启动服务以加载我需要的数据,然后将 json 异步传递给这些片段。

我是 android 和一般编程的新手,所以如果我的行为不明智,请原谅,但我首先尝试将片段注册为接收器,然后简单地广播包含捆绑包中的 json 信息的意图。这似乎不起作用,因为有时当服务广播意图并错过意图时片段不会运行。

然后我决定采用粘性意图,但这导致信息陈旧,更不用说继承安全问题了。

让服务在启动应用程序时执行后台网络请求,然后稍后通过任何活动或片段显示返回的信息的最佳方式是什么?

【问题讨论】:

标签: java android android-intent android-fragments android-service


【解决方案1】:

相信我,我在大型企业项目中尝试了很多第三方方法(服务总线、观察器等),结果证明原生 Android 机制是最快和最强大的,因为它们利用了框架的好处。

这就是为什么我建议将 LocalBroadcastManager 与 BroadcastReceiver 一起使用。在您的活动(或您的活动中按片段执行此操作!)在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);

【讨论】:

    【解决方案2】:

    您不仅可以从初始屏幕调用 startService(),还可以从片段调用 startService():getActivity().startService()

    Service(而不是 IntentService)派生您的服务。在onStartCommand() 中,它将从网络中读取数据,然后广播结果。如果结果已经加载,服务可以简单地广播结果。

    当您从初始屏幕调用startService() 时,服务会从网络加载数据并将其广播到当前显示的片段。新片段创建后,再次调用startService(),服务广播缓存数据。

    另一种方法是bindService。您的片段可以绑定到onCreate() 上的服务并在onDestroy() 上解除绑定。在这种情况下,fragment 可以直接调用服务的方法。

    【讨论】:

    • 谢谢你的解释正是我想要的
    【解决方案3】:

    使用事件总线而不是广播意图,例如Green Robot EventBus(也支持粘性广播)

    【讨论】: