我用AIDL接口插了一堵墙。我有一个必须通过第三方应用程序控制的应用程序(我对此有足够的控制权,所以我可以让他们在我们的活动中实现我需要的东西)
最初我的应用程序也是一个带有界面和活动的活动,但我已将其更改为后台服务并进行测试,我创建了一个虚拟应用程序,设法将服务应用程序启动到后台。
现在我想要一种从服务请求方法调用的方法(主要是:start,stop,sendData)。我已经为这两个应用创建了.aidl文件。 aidl文件只实现了一种方法(这是其中一些其他问题的礼貌。)
package foo.testapp;
interface IScript
{
String executeScript(String script);
}
除了包装是“foo.otherapp”之外,其他的援助是相同的。我在网上找到的实现对于两个aidl文件都有相同的包,但对我来说这会导致错误(猜测这只是我的问题,因为我讨厌名称空间和包,所以我经常只是命名它们,如果它很重要改变它们,我可以做到)
计划是使用此方法将字符串发送到服务,只需切换预定义的字符串即可调用正确的方法(如果改进了用法,也可以实现三种不同的方法)。
无论如何......我无法让aidl连接,我收到错误“无法启动服务意图
{act = foo.testapp.IScript}:未找到
我猜这与我的误解有关,即。包名等)
这是我的测试活动应用
中的实施private final IScript.Stub mBinder = new IScript.Stub()
{
@Override
public String executeScript(String script) throws RemoteException
{
// TODO Auto-generated method stub
}
};
IScript mService = null;
private ServiceConnection mConnection = new ServiceConnection()
{
public void onServiceConnected(ComponentName className, IBinder service)
{
mService = IScript.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName className)
{
mService = null;
}
};
然后在OnCreate()方法中我会这样做:
bindService(new Intent(IScript.class.getName()),
mConnection, Context.BIND_AUTO_CREATE);
在服务类我有这个;
@Override
public IBinder onBind(Intent intent)
{
// Select the interface to return. If your service only implements
// a single interface, you can just return it here without checking
// the Intent.
if (IScript.class.getName().equals(intent.getAction()))
{
return mBinder;
}
return null;
}
/**
* The IRemoteInterface is defined through IDL
*/
private final IScript.Stub mBinder = new IScript.Stub()
{
@Override
public String executeScript(String script) throws RemoteException
{
if (script == "test")
{
return "foo";
}
return "fail";
}
};
最后是清单文件;
实际上,在处理aidl时,我不知道是否必须在清单文件中添加内容。在一个例子中,我看到了这一点; <intent-filter>
<action android:name="foo.otherapp.IScript" />
</intent-filter>
和
<intent-filter>
<action android:name="foo.testapp.IScript" />
</intent-filter>
我猜错误可能在任何地方。我一直试图用口香糖和创可贴来解决这个问题。猜猜我刚刚误解了一些基本概念。
无论如何,欢迎任何帮助。
提前致谢!
答案 0 :(得分:3)
我决定回答我自己的问题,因为我找到了一个确切的解决方案。
只需通过复制粘贴源代码并正确更改包名称和函数名称(假设您将其实现到您自己的项目中),所有工作都可以正常工作。
来自客户端文件夹的源转到客户端活动,serviceimpl转到服务。我不需要“服务”活动,所以我把它留了出去(而且它似乎并没有被调用)。
我没有足够的声誉来发布多个链接,因此您可以从页面顶部获取来源。
&#34;更新:请查看Android SDK 1.5的更新示例程序。&#34;
答案 1 :(得分:1)
我也在努力解决这个问题。您的猜测是正确的,RemoteInterface.aidl需要在服务和测试应用程序中具有相同的包名称 - 那么您在哪里放置它??
如果您正在使用Eclipse进行开发,那么诀窍就是拥有一个公共源文件夹(两个项目共有)将此文件夹放在两个项目之外,并在构建属性/源中,单击“链接源”并浏览到该位置共同的来源。 (您可以将其命名为您想要的任何名称)在两个项目中执行此操作并将interface.aidl放在那里。它将出现在两个项目的Package Explorer中,当你在一个项目中更改它时,另一个项目也会更新。
在公共源文件夹中,我将interface.aidl放在一个与服务同名的包中。
如果你使用Ant来构建,它会有点棘手,因为默认的ant_rules.xml不支持两个aidl文件夹,你必须修改你的build.xml,添加一个新的目标和它的所有依赖。
我的项目是通过调整第17章中的“下载源”示例来实现的: