Using android API in APK Bundle gives: "Could not find class 'android.content.Context', referenced from method com.example.patient.Activator.start"

StackOverflow https://stackoverflow.com/questions/20222620

سؤال

I am embedding OSGI framework into Android application. Beside my android application, I have an APK bundle that I create using the following steps:

  • Create a regular APK, for example by creating Eclipse Android Project.
  • Make your bundle use the same OSGI framework library used by your application by: Build Path->Configure Build Path->Projects, and then add your application project that will load the bundle. Your application project should contain the OSGI framework jar file in its build path, (in my case felix.jar).
  • Create the bundle manifest file describing the bundle. You can call it bundle.manifest.
  • Say your application package is 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.
  • Use Android Tools > Export Unsigned Android Package
  • Copy bundle.manifest to the root directory of the generated unsigned APK as META-INF/MANIFEST.MF. You can use Winzip to open the unsigned APK and add the folder META-INF.
  • Sign the APK using the command: jarsigner -verbose -keystore /path_to_keystore/mykeystore.keystore my_application.apk my_keystore_alias.
  • Copy your directory that contains all the .class files from your android project to the root directory of your signed apk. In my case: it is the com directory.
  • Sign your APK once again.
  • Install the APK bundle.
  • Have the OSGi framework load and start the APK bundle (the very same APK file)

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!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top