2011-01-11 28 views
3

我用AIDL接口卡住了一堵墙。我有一个应用程序必须通过第三方应用程序进行控制(我已经对此有足够的控制权,所以我可以要求他们实施我需要的任何活动)两个应用程序之间的AIDL接口

本来我的应用程序也是一个具有界面和一切,但我已经改变它作为后台服务和测试,我创建了一个虚拟应用程序,设法启动服务应用程序的背景。

现在我想从服务请求方法调用(主要是;开始,停止,sendData)的方式。我为这两个应用程序创建了.aidl文件。而其他AIDL是相同的,除了这个包是“foo.otherapp”的AIDL文件实现只有一个方法(这是一些其他问题的礼貌在这里。)

package foo.testapp; 
interface IScript 
{ 
    String executeScript(String script); 
} 

。我在网上找到的实现对这两个aidl文件都有相同的包,但是对于我来说这会导致一个错误(猜测这只是我的一个问题,因为我讨厌命名空间和包,所以我经常只是给它们起名字,如果它很重要改变它们,我可以做到)

计划是使用这种方法向服务发送一个字符串,并且只需切换预定义的字符串即可调用正确的方法(如果它改进了,也可以实现三种不同的方法用法)。

反正......我不能让AIDL连接时,我得到错误“无法启动服务意向

{行为= foo.testapp.IScript}:找不到

我这个猜测有事情做与我的误解,即。packagenames左右)

这是在我的测试活动应用实施

在OnCreate中
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; 
    } 
}; 

然后()方法,我会做到这一点:

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时是否需要在manifest文件中添加一些东西。在一个例子中,我看到了这个;

<intent-filter> 
     <action android:name="foo.otherapp.IScript" /> 
    </intent-filter> 

<intent-filter> 
     <action android:name="foo.testapp.IScript" /> 
    </intent-filter> 

我猜想,这些错误可能在任何地方。我一直试图用口香糖和创可贴来设置它。猜猜我刚刚误解了这个基本概念。

无论如何,任何帮助是值得欢迎的。

在此先感谢!

回答

3

我决定回答我的问题,因为我找到了一个精确解。

My Life With Android

一切都只是工作通过复制粘贴的来源和正确更改包名和函数名(假设你实现这个到自己的项目),从客户端文件夹

来源前往客户端活动和serviceimpl去服务。我不需要'服务活动',所以我把它排除了(而且它似乎并没有被调用过)。

我没有足够的声望发布多个链接,因此您可以从页面顶部获取源代码。

“更新:请查看Android SDK 1.5的更新示例程序。”

1

我也在为此而苦苦挣扎。你猜对了RemoteInterface是正确的。aidl需要在服务和测试应用程序中使用相同的软件包名称 - 所以你把它放在哪里!?

如果你在Eclipse中开发,那么诀窍是有一个通用的源文件夹(两个项目都是共同的)使这个文件夹在两个项目之外,并在构建属性/源,点击“链接源”并浏览到共同来源的位置。 (你可以称它为任何你想要的名字)在两个项目中做这个,并把interface.aidl放在那里。它会出现在两个项目的包资源管理器中,当您在一个项目中更改它时,另一个项目也会更新。

在通用源文件夹中,我将interface.aidl放入与服务同名的包中。

如果你使用Ant来构建,它会有点棘手,因为默认的ant_rules.xml不支持两个aidl文件夹,你必须修改你的build.xml很大一部分添加一个新的目标和它的所有依赖。

我得到了我的项目从“下载源”在这里通过调整样本会形成第17章:

link text

+0

感谢您的建议。我昨天很快就试过了,尽管如此还是无法​​解决这个问题。然后,我试着重新构建包名,使其与最终的唯一.service和.client相同。所以foo.projectname.client&foo.projectname.service。这导致我陷入了一个令人讨厌的错误,现在导致了很多灰色头发,应用程序无法在模拟器上安装某些... 70-80%的错误类没有找到,有时只是安装顺利开始。所以我想我会根据您发布的来源重写绑定。结果回来,希望今天。 – 2011-01-12 09:07:39

相关问题