I am embedding OSGI framework into Android application. Beside my android application, I have an APK bundle that I create using the following steps:
felix.jar
).bundle.manifest
.com.acme.helloworld
(this value is
set with manifest:package in AndroidManifest.xml
), your OSGI bundle's
Activator class MUST be placed in the package com.acme.helloworld
and
you MUST set Bundle-SymbolicName: com.acme.helloworld
in the bundle
manifest. If any of these conditions is not met then will result in a
java.lang.NoClassDefFoundError
on runtime.META-INF/MANIFEST.MF
. You can use Winzip to open the unsigned
APK and add the folder META-INF
.jarsigner -verbose -keystore
/path_to_keystore/mykeystore.keystore my_application.apk my_keystore_alias
.com
directory.Using these steps, I successfully loaded the APK bundle to Felix framework, and It starts OK.
However, I am now trying to launch an activity that exists in the APK bundle, so I did the following:
In my Application project, I register the application context as a service to make it available for the APK bundle:
// Register the application's context as an OSGi service!
BundleContext bundleContext = m_felix.getBundleContext();
ServiceRegistration regContext = bundleContext.registerService(Context.class,
getApplicationContext(), new Hashtable());
In my APK bundle start
method() in the Activator
class:
ServiceReference<Context> ref = bundleContext.getServiceReference(Context.class);
final Context ctx = bundleContext.getService(ref);
Intent intent = new Intent();
String pkgName = View_Patient_File_Activity.class.getPackage().getName();
String clssName = View_Patient_File_Activity.class.getName();
intent.setClassName(pkgName, clssName);
// You may add the NEW_TASK flag
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Important: do not use startActivity(Context, Class) version because it will fail to resolve the activity
ctx.startActivity(intent);
When I run my application project, the bundle is not installed because of the following errors:
11-26 20:07:06.600: W/dalvikvm(24646): VFY: unable to find class referenced in signature (Lorg/osgi/framework/BundleContext;)
11-26 20:07:06.600: W/dalvikvm(24646): VFY: unable to find class referenced in signature (Lorg/osgi/framework/BundleContext;)
11-26 20:07:06.600: E/dalvikvm(24646): Could not find class 'android.content.Context', referenced from method com.example.patient.Activator.start
11-26 20:07:06.600: W/dalvikvm(24646): VFY: unable to resolve const-class 25 (Landroid/content/Context;) in Lcom/example/patient/Activator;
11-26 20:07:06.600: D/dalvikvm(24646): VFY: replacing opcode 0x1c at 0x0009
11-26 20:07:06.600: W/dalvikvm(24646): VFY: unable to find class referenced in signature (Lorg/osgi/framework/BundleContext;)
11-26 20:07:06.600: W/dalvikvm(24646): Method mismatch: start in Lcom/example/patient/Activator; (cl=0x4072f3c0) and iface Lorg/osgi/framework/BundleActivator; (cl=0x40712e88)
11-26 20:07:06.600: W/dalvikvm(24646): Class init failed in newInstance call (Lcom/example/patient/Activator;)
11-26 20:07:06.600: E/Zaid Log(24646): Problem installing the bundle :s
11-26 20:07:06.600: W/System.err(24646): org.osgi.framework.BundleException: Activator start error in bundle com.example.patient [1].
11-26 20:07:06.600: W/System.err(24646): at org.apache.felix.framework.Felix.activateBundle(Felix.java:2196)
11-26 20:07:06.600: W/System.err(24646): at org.apache.felix.framework.Felix.startBundle(Felix.java:2064)
11-26 20:07:06.600: W/System.err(24646): at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)
11-26 20:07:06.600: W/System.err(24646): at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:942)
11-26 20:07:06.600: W/System.err(24646): at com.example.patient_application.MainActivity.onCreate(MainActivity.java:149)
11-26 20:07:06.600: W/System.err(24646): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
11-26 20:07:06.600: W/System.err(24646): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1715)
11-26 20:07:06.600: W/System.err(24646): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1767)
11-26 20:07:06.600: W/System.err(24646): at android.app.ActivityThread.access$1500(ActivityThread.java:122)
11-26 20:07:06.600: W/System.err(24646): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1005)
11-26 20:07:06.600: W/System.err(24646): at android.os.Handler.dispatchMessage(Handler.java:99)
11-26 20:07:06.600: W/System.err(24646): at android.os.Looper.loop(Looper.java:132)
11-26 20:07:06.600: W/System.err(24646): at android.app.ActivityThread.main(ActivityThread.java:4028)
11-26 20:07:06.600: W/System.err(24646): at java.lang.reflect.Method.invokeNative(Native Method)
11-26 20:07:06.600: W/System.err(24646): at java.lang.reflect.Method.invoke(Method.java:491)
11-26 20:07:06.600: W/System.err(24646): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
11-26 20:07:06.600: W/System.err(24646): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
11-26 20:07:06.600: W/System.err(24646): at dalvik.system.NativeStart.main(Native Method)
11-26 20:07:06.600: W/System.err(24646): Caused by: java.lang.LinkageError: Classes resolve differently in interface
11-26 20:07:06.600: W/System.err(24646): at java.lang.Class.newInstanceImpl(Native Method)
11-26 20:07:06.600: W/System.err(24646): at java.lang.Class.newInstance(Class.java:1301)
11-26 20:07:06.600: W/System.err(24646): at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:4336)
11-26 20:07:06.600: W/System.err(24646): at org.apache.felix.framework.Felix.activateBundle(Felix.java:2141)
11-26 20:07:06.600: W/System.err(24646): ... 17 more
11-26 20:07:06.610: V/TLINE(24646): new: android.text.TextLine@40782610
11-26 20:07:06.700: D/CLIPBOARD(24646): Hide Clipboard dialog at Starting input: finished by someone else... !
I exported the android packages in my application project like this:
static final String ANDROID_FRAMEWORK_PACKAGES = (
"android,"
+ "android.app,"
+ "android.content,"
+ "android.database,"
+ "android.database.sqlite,"
+ "android.graphics,"
+ "android.graphics.drawable,"
+ "android.graphics.glutils,"
+ "android.hardware,"
+ "android.location,"
+ "android.media,"
+ "android.net,"
+ "android.net.wifi,"
+ "android.opengl,"
+ "android.os,"
+ "android.provider,"
+ "android.sax,"
+ "android.speech.recognition,"
+ "android.telephony,"
+ "android.telephony.gsm,"
+ "android.text,"
+ "android.text.method,"
+ "android.text.style,"
+ "android.text.util,"
+ "android.util,"
+ "android.view,"
+ "android.view.animation,"
+ "android.webkit,"
+ "android.widget");
m_configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA,
ANDROID_FRAMEWORK_PACKAGES);
And I import these packages in my APK bundle. Below is my MANIFEST.MF
Manifest-Version: 1.0
Bundle-Vendor: Zaid
Bundle-Version: 1.0.0
Bundle-Name: Patient
Bundle-ManifestVersion: 2
Bundle-Activator: com.example.patient.Activator
Bundle-Description: View Patient File
Bundle-SymbolicName: com.example.patient
Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.0
Import-Package: android, android.app, android.content, org.osgi.framework
The same errors keep coming again and again. Can someone help? Thank you.
Note: I took Most of these ideas, and the code from the user @slash33 who had a previous experience with this topic.
The problem turned out to be in my MANIFEST.MF
file. I could not locate the error, but I used an old copy of the file, and then all the errors disappeared. Below is my updated MANIFEST.MF
file
Manifest-Version: 1.0
Bundle-Vendor: Zaid
Bundle-Version: 1.0.0
Bundle-Name: Patient
Bundle-ManifestVersion: 2
Bundle-Activator: com.example.patient.Activator
Bundle-Description: View Patient File
Import-Package: org.osgi.framework, android.content
Bundle-SymbolicName: com.example.patient
Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.0
My APK bundle was successfully loaded to Felix framework and I am now able to launch activities inside the bundle. Thanks God!