如何将消息/数据从广播接收器(process1)发送到android中的服务线程(process2)?

Posted

技术标签:

【中文标题】如何将消息/数据从广播接收器(process1)发送到android中的服务线程(process2)?【英文标题】:How to send message/data from broadcast receiver (process1) to Service thread (process2) in android? 【发布时间】:2013-05-07 16:01:54 【问题描述】:

我正在开发一个安卓应用程序。此应用程序架构分为 5 个模块,其中 2 个模块具有多种功能。为了开发这个应用程序,我根据需要创建了 2 个进程,其中包含多个线程和 3 个其他线程。我对此实现有一些疑问:

这是一个好模型吗?如果不是,为什么不呢?现在我只考虑模块化。

我需要从 process1 中的广播接收器向 process2 中的服务线程发送消息,最好的方法是什么?

android 中最好的 IPC 机制是什么?我尝试使用这个链接,http://androidapps.org.ua/androidintro_ipc_intent.html,它建议 startActivity 和 startActivityForResult,但是这些选项在广播接收器中不可用,并且服务没有 startActivityForResult 选项。

谢谢。

【问题讨论】:

【参考方案1】:

使用自定义BroadcastReceiver

把这个写在 ActivityA.java

 Intent intent = new Intent();
 intent.putExtra("message","hi");
 intent.setAction("com.android.activity.SEND_DATA");
 sendBroadcast(intent); 

把这个写在 ServiceA.java

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() 
@Override
public void onReceive(Context context, Intent intent) 
   // Extract data included in the Intent
   String message = intent.getStringExtra("message");
   Log.d("receiver", "Got message: " + message);
  
;

现在注册Receiver

LocalBroadcastManager.getInstance(mContext).registerReceiver(mMessageReceiver,
  new IntentFilter("com.android.activity.SEND_DATA"));   

【讨论】:

嘿Rstar,我需要从Broadcastreceiver 的onReceive 函数向服务发送一条消息,它们位于不同的服务上。我可以做后面的部分,即在服务中创建另一个广播接收器。但是对于第一部分我没有看到选项,在 Broadcastreceiver 的 onReceive 函数中的 sendBroadcast。 您不想发送广播意图只是为了将数据传递给服务。您可以直接执行此操作。 @DavidWasser 是对的,如果您不想使用 BroadcastReceiver @Rstar 我可以从服务而不是活动发送广播吗?否则我必须在 sendBroadcast 中进行更改。如果是,那么这正是我想要的【参考方案2】:

只需在BroadcastReceiver 中创建一个Intent,将您的数据添加为额外的,可以使用Intent 调用startService()

Intent intent = new Intent(context, MyService.class);
intent.putExtra("message", "whatever data you need to pass to the service");
context.startService(intent);

方法onStartCommand() 将在您的服务中调用Intent

要回答您的另一个问题“什么是最好的 IPC 方法”,答案(一如既往)是“这取决于”。使用Intents 是最简单的方法,因为它支持所有开箱即用的组件。如果您需要在组件之间进行更复杂的交互,您可以考虑使用 AIDL,这将允许您在 Service 中进行远程方法调用。如果这还不够,那么只需在 2 个组件之间实现您自己的套接字协议。

【讨论】:

大卫,还有一个问题,假设我正在尝试将数据/消息发送到另一个进程中的活动(而不是服务),该怎么做? 抱歉,您在onReceive() 中的context 参数上调用了startService()。我修复了我的代码。 如果你想向一个活动发送数据/消息,你做的完全一样。您创建一个Intent,将您的数据添加为附加数据并调用context.startActivity()。您可以在任何流程中启动 Activity(实际上,当您启动 Activity 时,您真的不知道或无法控制它将在哪个流程中启动)。 是的,但是如果活动已经在运行呢? sudhee 回答了我的问题,即使用标志。 如果活动已经在运行,默认行为是创建该活动的另一个实例。但是,如果您使用Intent.FLAG_ACTIVITY_SINGLE_TOP 或者如果活动是使用launchMode="singleTop" 定义的,那么Intent 将使用onNewIntent() 传递给现有活动。【参考方案3】:

首先,尝试理解您的术语。通过流程,我假设您的意思是活动和“服务线程”,我假设您的意思是服务。

如果您想从在 Activity 1 的上下文中运行的 onReceive() 广播接收器向已经处于活动状态的服务发送消息,您可以尝试以下方法之一:

1) 创建一个新的intent(服务类名作为类),并用intent调用startService()。添加您需要的附加参数作为意图附加项。不管您的服务是否已经处于活动状态,仍然调用 onStartCommand(),您可以使用特殊参数作为附加意图来区分 onStartCommand() 和 onReceive。

2) 如果您的场景允许这样做,请考虑在您的活动和服务中注册到相同的广播事件并采取适当的行动(然后无需传递消息)

3) 在您的服务中编写另一个广播接收器,并从 Activity 的广播接收器调用 sendBroadcast()

【讨论】:

不,进程并不意味着活动,是的服务线程我的意思是服务。我在 Broadcastreceiver 的 onReceive 函数中看不到 startService 和 sendBroadcast 选项。 Eclipse 说这些方法不存在,实现它们。我不明白选项 2。 您是否有清单定义的广播接收器或动态注册的接收器? 使用 registerReceiver(localFaultDetector, batteryLifeFilter) 动态注册;这个方法。 使用作为 onReceive() 的参数 1 传递的上下文,例如:arg0.startActivity() 或 arg0.sendBroadcast() 选项 2 的明确性:我的意思是你在你的“进程”和服务中注册到同一个广播事件,并且两者都编码了 onReceive()。您将在这两个地方收到广播。但是,如果您在将“流程”传递给您的服务之前需要在“流程”中进行一些额外的处理,这将不起作用。

以上是关于如何将消息/数据从广播接收器(process1)发送到android中的服务线程(process2)?的主要内容,如果未能解决你的问题,请参考以下文章

如何将结果数据从广播接收器发送到活动

当有多个服务器广播时,客户端如何接收多个广播消息?

急!!Android系统中,广播Intent的问题

Coffeescript没有从广播消息中继作业接收数据

如何从服务获取数据到活动

探测 MPI_Bcast 或 MPI_Send