android将字符串发送到在另一个进程中运行的服务
Posted
技术标签:
【中文标题】android将字符串发送到在另一个进程中运行的服务【英文标题】:android send string to a service running in another process 【发布时间】:2012-03-07 18:48:00 【问题描述】:我正在使用this 教程来帮助我使用即使应用程序本身在后台也将始终在后台运行的服务,并且我希望能够在我的主进程和服务之间传输字符串. 问题是,我到处都看到编组字符串应该很容易,但对于更复杂的东西,需要 AIDL。 由于我只想发送字符串消息,我想一定有一个非常简单的方法可以做到这一点,但我找不到它..
谢谢
【问题讨论】:
【参考方案1】:我想意图服务是要走的路。 如何创建 Intent 服务说明here
【讨论】:
【参考方案2】:好的,这是一个 非常 hackish 的解决方案,非常不像 OOP,但这是我最终做的,所以如果有人发现需要一个简单的,我就把它放在这里,不是很优雅(但有效)的解决方案。
我使用sendBroadcast
和broadcastReceiver
在服务和应用程序之间进行通信。
问题是由于某种原因跨进程发送意图会删除所有额外内容,所以我改用SharedPrefences
。
这是我用来发布和订阅此类字符串消息传递的(单例)类。
访客界面
public interface Visitor<T>
public void visit(T element);
发布订阅者接口:
public interface IPulishSubscribe
/**
* Publish a new string message
*
* @param key The key to publish under
* @param text The message's content
*/
public void publish(String key, String text);
/**
* Subscribe to a message
*
* @param key The key to subscribe to
* @param visitor The visitor to handle the message when received
*/
public void subscribe(final String key, final Visitor<String> visitor);
实现
public class PublishSubscriber implements IPulishSubscribe
private static IPulishSubscribe _instance = new PublishSubscriber();
private static Context _context;
// key -> handler, isn't of much use ATM, but you may need it for removals...
private Map<String, BroadcastReceiver> _subscribers = new HashMap<String, BroadcastReceiver>();
private PublishSubscriber()
public static void init(Context context)
_context = context;
public static IPulishSubscribe getInstance()
return _instance;
@Override
public synchronized void publish(String key, String text)
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(_context);
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString(key, text);
editor.commit();
_context.sendBroadcast(new Intent(key));
@Override
public synchronized void subscribe(final String key, final Visitor<String> visitor)
BroadcastReceiver newSubscriber = new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(_context);
String data = mPrefs.getString(key, null);
if (visitor != null)
visitor.visit(data);
;
_context.registerReceiver(newSubscriber, new IntentFilter(key));
_subscribers.put(key, newSubscriber);
【讨论】:
【参考方案3】:@Gal 我喜欢你的回答。我不知道它有多快,但我希望它能完成你的工作。
我也遇到过这个问题。我的第一次尝试是 Messenger api,如服务文档中所示。它有效,但对您可以发送的内容相当有限。您必须使用 Bundle 来发送字符串。
Message msg = Message.obtain();
Bundle data = new Bundle(1); // size of Bundle array
data.putString("anything");
messenger.send(msg);
如果您不想不断创建新对象,则重用 Message 和 Bundle 对象存在一些细微差别。
然后我尝试了 AIDL,以便更轻松地进行进程间通信。但是在构建了 api 之后,我点击了发送发送发送,什么也没看到。
我尝试的最后一种方法是使用文件。简单地创建一个文件,写入它并在另一端读取它。听起来很容易,但要正常工作却很难。然后您必须了解文件会不断增长。
class Service_ extends Service
@Override protected void onCreate
new FileObserver("/sdcard/IFILE")
@Override public void onEvent(int event,String path)
if(event == MODIFY) // Client sent message
class Client extends ServiceConnection
java.io.RandomAccessFile serviceWriter = new java.io.RandomAccessFile("/sdcard/IFILE");
我一直面临的问题是 FileObserver 似乎总是收到文件修改通知,但我的服务无法读取客户端发送一次的 INIT 指令,以便服务可以创建支持控制台活动。
另一件事是,android 本质上是 Linux。 Linux 具有在进程之间发送消息和文件句柄的原始方法。至少在 C api 中。
【讨论】:
以上是关于android将字符串发送到在另一个进程中运行的服务的主要内容,如果未能解决你的问题,请参考以下文章
如何将命令发送到在 perl 的非标准端口上运行的 telnet
将Visual Studio 2012附加到在Android移动设备上运行的Unity游戏中,以进行调试
将 Ctrl+C 事件发送到在 Windows 上使用 QProcess 启动的进程
将 PHP 调用的 .exe 程序(作为单独的进程,而不是在 PHP 中运行)的输出发送回 iPhone 客户端的可能方法