如何使用PendingIntent从服务交stream到客户/活动?

我一直在Android开发者网站上阅读以下文字,特别是在框架话题 – >服务 – >启动服务 。

在那里说明如下:

如果服务不提供绑定,则使用startService()提供的意图是应用程序组件和服务之间唯一的通信模式。 但是,如果您希望服务发回结果,则启动该服务的客户端可以为广播(使用getBroadcast())创build一个PendingIntent并将其传递到启动该服务的Intent中的服务。 该服务然后可以使用广播来传递结果。

我有几个关于这个问题的问题:

  1. 这个文本是否适用于Service IntentService
  2. 应该如何(代码方式)从Service内实现这一点; 该服务然后可以使用广播来传递结果。 以及所提到的广播将结果交付给原始客户/活动的地点? 有一些方法应该被覆盖(如onActivityResult() )或什么的?

Solutions Collecting From Web of "如何使用PendingIntent从服务交stream到客户/活动?"

问题在几个月前被问过,但如果有人还在寻找答案,我希望我能帮上忙。

在下面的例子中,我们有本地服务,负责执行一些耗时的操作。 活动向服务发出请求,但不绑定到服务 – 只是发送请求的意图。 另外,Activity包含了BroadcastReceiver的信息,当服务完成所请求的任务时应该被callback。 信息由PendingIntent传递。 服务在后台线程中处理任务,当任务完成时,服务以回答广播BroadcastReceiver。

1.创buildBroadcastReceiver子类:

 public class DataBroadcastReceiver extends BroadcastReceiver { static Logger log = LoggerFactory.getLogger(DataRequestService.class); @Override public void onReceive(Context context, Intent intent) { log.info(" onReceive"); } } 

当任务完成时,这个广播接收机将从服务通知。

2.创build服务

 public class DataRequestService extends Service { private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { log.info("handleMessage"); //... performing some time-consuming operation Bundle bundle = msg.getData(); PendingIntent receiver = bundle.getParcelable("receiver"); // Perform the operation associated with PendingIntent try { //you can attach data from the operation in the intent. Intent intent = new Intent(); Bundle b = new Bundle(); //b.putString("key", value); intent.putExtras(b); receiver.send(getApplicationContext(), status, intent); } catch (CanceledException e) { e.printStackTrace(); } } } @Override public void onStart(Intent intent, int startId) { Bundle bundle = intent.getExtras(); msg.setData(bundle); mServiceHandler.sendMessage(msg); } 

那么,最重要的部分是在handleMessage()方法。 服务只是将广播操作传送给广播接收器。

3.您还需要在Manifest.xml中注册您的广播接收机和服务

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ramps.servicetest" android:versionCode="1" android:versionName="1.0" > .... <service android:name=".service.DataRequestService" android:exported="false"/> <receiver android:name=".service.DataBroadcastReceiver"></receiver> </application> </manifest><br> 

4.最后,从活动向您的服务请求:

 Intent serviceIntent = new Intent(context, DataRequestService.class); @Override public void onClick(View v) { //this is the intent that will be broadcasted by service. Intent broadcastReceiverIntent = new Intent(context, DataBroadcastReceiver.class); //create pending intent for broadcasting the DataBroadcastReceiver PendingIntent pi = PendingIntent.getBroadcast(context, 0, broadcastReceiverIntent, 0); Bundle bundle = new Bundle(); bundle.putParcelable("receiver", pi); //we want to start our service (for handling our time-consuming operation) Intent serviceIntent = new Intent(context, DataRequestService.class); serviceIntent.putExtras(bundle); context.startService(serviceIntent); } 

5.对原始客户/活动提供回应

您可以从中抽取所有活动将要扩展的活动。 这种绝对活动可以自动注册/注销自己作为广播接收器中的响应监听器。 实际上这里没有太多的选项,但重要的是,如果您保持对活动的静态引用,则必须在活动被销毁时删除引用。

问候,
坡道

为了执行服务活动之间的沟通。 您也可以使用官方Android示例中提到的Binder http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

有关详细的解释,请参阅此答案 https://stackoverflow.com/a/36983011/4754141