Problem: A Service called PdService is “not found” during execution when I send an Intent to bind it from an Activity.
[Edit: Solution]
I am not crystal clear on the issues surrounding the solution, however a solution has been found. When I export the JAR of my main project (which is linked to an Android library project), I choose the option to include the library project in the JAR as well. This fixed the problem.
Now, its strange because the source code from the linked project was clearly making it into the JAR even before this, it just was not being “found” by the Android runtime. But for some reason explicitly including the entire linked project has fixed this issue. Its also an unfortunate workaround because I now have to include far more content in my JAR than I want to, but for now the problem is resolved.
[Original Problem Details]
Details:
- The app is an AIR for Android app (.SWF + OTHER_STUFF -> .APK)
- The java code (including PdService) has been packaged in an AIR Native Extension (.ane)
- The Intent for PdService occurs within our custom FREContext (see AIR Native Extensions) which we have called PdContext, specifically in a method called init().
- For completeness, I have included the tag for PdService in both the extension’s Android manifest, as well as the AIR application’s application.xml file.
- The package name of the extension is: com.nichemobile.pd.pdextension
- The class path of PdService is: org.puredata.android.service.PdService
- The ID of the end-user application (AIR ID) is: com.nichemobile.pdextension.testapp
I have tried a number of combinations of Intents including (thisActivity is a reference to the executing 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");
Each Intent results in a runtime error claiming the service is “not found”. Does anyone have any idea how to correct this?
Based on my understanding of Intents for Services, the two parameters SHOULD be:
package: air.com.nichemobile.pdextension.testapp
class: org.puredata.android.service.PDService
But of course that did not work above in the very 1st example.
My current theory:
Upon inspecting the classes.dex file in the compiled APK, I found that at the root of this classes.dex file, there are 3 subdirectories:
- air.com.nichemobile.pdextension.testapp (contains AppEntry Activity)
- com (contains our extension Java classes)
- org.puredata (contains all the PD classes including PdService)
I am wondering if the app cannot locate Services because they exist outside of the “air.com.nichemobile.pdextension.testapp” directory within the classes.dex file. Now, the app can execute code in classes in the /com and /org.puredata directories – but I’m wondering if the process for starting a Service on the Android platform is somehow being interfered with by this class structure in the classes.dex file.
As a somewhat perplexing example of what I’m talking about above – the line before I try to bind this service, I can say:
Log.d(TAG, "PdService package: " + PdService.class.getPackage());
Log.d(TAG, "PdService class name: " + PdService.class.getName());
and I get output:
PdService package: package org.puredata.android.service
PdService class name: org.puredata.android.service.PdService
Any clarification here will be appreciated.
Thanks.
Matt
I am not crystal clear on the issues surrounding the solution, however a solution has been found. When I export the JAR of my main project (which is linked to an Android library project), I choose the option to include the library project in the JAR as well. This fixed the problem.
Now, its strange because the source code from the linked project was clearly making it into the JAR even before this, it just was not being “found” by the Android runtime. But for some reason explicitly including the entire linked project has fixed this issue. Its also an unfortunate workaround because I now have to include far more content in my JAR than I want to, but for now the problem is resolved.