Android服务与多个片段通信

3
我有一个应用程序,它有一个单一的活动,以自定义导航抽屉设计方式承载多个碎片。其中两个碎片依赖于服务来返回json信息以显示。我希望能够在启动画面上启动服务来加载所需数据,然后异步地将json通信到这些碎片。
我是新手,并且对Android和编程一般不太熟悉,因此请原谅我如果我的操作不合适,但我首先尝试将碎片注册为接收器,然后简单地广播包含json信息的意图。这似乎行不通,因为有时服务广播意图时碎片没有运行,会错过意图。
然后我决定使用粘性意图,但这导致信息陈旧,更不用说继承的安全问题了。
有什么最好的方法让一个服务在启动应用程序时执行后台网络请求,然后稍后由任何活动或片段显示返回的信息?

使用LocalBroadcastManager时不会存在安全问题。http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html - André Diermann
3个回答

6
相信我,在大型企业项目中,我尝试了许多第三方方法(服务总线、观察者等),结果发现原生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));
   }
}

在广播接收器的onReceive方法中,您可以根据接收到的广播执行所需的操作。如果您需要进一步区分,可以使用不同的操作或额外信息,例如在您的服务中:
...send(new Intent(INTENT_ACTION_SOMETHING_ELSE));

或者

send(new Intent(...).putExtra(WAS_SUCCESSFUL, false));
send(new Intent(...).putExtra(DOWNLOADED_CONTENT, downloadedStuff);

2

您不仅可以从启动画面,还可以从片段中调用startService(): getActivity().startService().

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

当您从启动画面调用startService()时,服务会从网络加载数据并将其广播给当前显示的片段。创建新片段时,它会再次调用startService(),并且服务会广播缓存的数据。

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


谢谢,我认为你在这里的解释正是我所寻找的。 - feilong

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接