AIR for Android App - 找不到服务

时间:2011-12-04 07:07:59

标签: android service air

问题:当我发送Intent以从Activity绑定它时,在执行期间“找不到”名为PdService的服务。

[编辑:解决方案]

我对解决方案的问题并不十分清楚,但已找到解决方案。当我导出我的主项目的JAR(链接到Android库项目)时,我选择了将库项目包含在JAR中的选项。这解决了这个问题。

现在,它很奇怪,因为链接项目的源代码在此之前显然已经进入JAR,它只是没有被Android运行时“找到”。但出于某种原因明确包括整个链接项目已经解决了这个问题。它也是一个不幸的解决方法,因为我现在必须在我的JAR中包含比我想要的更多的内容,但是现在问题已经解决了。

[原始问题详情]

详细信息:

  • 该应用是适用于Android的AIR 应用(.SWF + OTHER_STUFF - > .APK)
  • java代码(包括PdService)已打包在 AIR Native Extension (.ane)
  • Intent for PdService发生在我们自定义的 FREContext (请参阅AIR Native Extensions)中,我们称之为PdContext,特别是在名为init()的方法中。
  • 为了完整起见,我在扩展程序的Android清单以及AIR应用程序的application.xml文件中都包含了PdService的标记。
  • 扩展程序包名称为: com.nichemobile.pd.pdextension
  • PdService的类路径为: org.puredata.android.service.PdService
  • 最终用户应用程序(AIR ID)的ID为: com.nichemobile.pdextension.testapp

我尝试了许多Intent组合,包括(thisActivity是对执行Activity的引用):

bindIntent.setClassName(thisActivity, "org.puredata.android.service.PDService");
bindIntent.setClassName(thisActivity, ".org.puredata.android.service.PDService");
bindIntent.setClassName(thisActivity, "..org.puredata.android.service.PDService");
bindIntent.setClassName("org.puredata.android.service", ".org.puredata.android.service.PDService");
bindIntent.setClassName("org.puredata.android.service", "org.puredata.android.service.PDService");
bindIntent.setClassName("", "org.puredata.android.service.PDService");
bindIntent.setClassName(".", "org.puredata.android.service.PDService");

每个Intent都会导致运行时错误,声称服务“未找到”。有没有人知道如何纠正这个?

根据我对Intents for Services的理解,这两个参数应该是: 包:air.com.nichemobile.pdextension.testapp class:org.puredata.android.service.PDService 但当然,在第一个例子中,这不起作用。

我目前的理论:

在检查编译好的APK中的classes.dex文件后,我发现在这个classes.dex文件的根目录下,有3个子目录:

  • air.com.nichemobile.pdextension.testapp(包含AppEntry活动)
  • com(包含我们的扩展Java类)
  • org.puredata(包含所有PD类,包括PdService)

我想知道应用程序是否找不到服务,因为它们存在于classes.dex文件中的“air.com.nichemobile.pdextension.testapp”目录之外。现在,应用程序可以在/ com和/org.puredata目录中的类中执行代码 - 但我想知道在Android平台上启动服务的过程是否在某种程度上受到classes.dex中此类结构的干扰文件。

作为我上面谈论的一个有点令人困惑的例子 - 在我尝试绑定此服务之前的那一行,我可以说:

Log.d(TAG, "PdService package: " + PdService.class.getPackage());
Log.d(TAG, "PdService class name: " + PdService.class.getName());

我得到了输出:

PdService package: package org.puredata.android.service
PdService class name: org.puredata.android.service.PdService

此处的任何澄清将不胜感激。

感谢。

马特

2 个答案:

答案 0 :(得分:1)

问题在于签名证书和AIR应用程序的包名称。

Adob​​e AIR Native Extensions规则

规则1。 代码签名证书包必须与app.xml中的应用程序ID匹配 因此,如果证书包为com.my.company,则航空应用ID必须为<id>com.my.company</id>

规则2。 使用ADT打包android的原生扩展时,会在包名称中添加前缀,使其看起来像air.com.my.company

当Android ActivityManager尝试运行您的服务时,它会在air.com.my.company中查找它。因此,Service类必须位于java代码中的相同包中(包括&#39; air&#39;前缀)。 Correct TestService类定义为air.com.my.company.TestService

使用以下清单,它运行得很好!

<application>
<activity android:name=".TestActivity">
    <intent-filter>
            <action android:name="TestActivity"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

<service android:enabled="true" android:exported="true" android:name=".TestService">
</service>
 </application>

答案 1 :(得分:0)

我对解决方案的问题并不十分清楚,但已找到解决方案。当我导出我的主项目的JAR(链接到Android库项目)时,我选择了将库项目包含在JAR中的选项。这解决了这个问题。

现在,它很奇怪,因为链接项目的源代码在此之前显然已经进入JAR,它只是没有被Android运行时“找到”。但出于某种原因明确包括整个链接项目已经解决了这个问题。它也是一个不幸的解决方法,因为我现在必须在我的JAR中包含比我想要的更多的内容,但是现在问题已经解决了。