Android Activity in OSGI Bundle

独自空忆成欢 提交于 2019-11-30 15:52:11
Traveling Salesman

There were two problems, and by solving them I managed to finally get my APK bundle installed and started on Felix.

1- Unlike OSGI bundles, the final signed APK does not contain the .class files. That's why I was getting: Not found: com.example.patient.Activator. By manually copying the com directory from my android project to the signed APK, and then signing it again, I managed to solve this problem.

2- The second step mentioned by @slash33 which is:

•add a Reference Library entry to the project Build Path for your OSGi framework

was causing me the following error:

 (Lcom/example/patient/Activator; had used a different Lorg/osgi/framework/BundleActivator; during pre-verification)

With help of this post, I simply deleted the reference to the library,and removed felix.jar from my build path. Then I did this: Build Path->Configure Build Path->Projects, and then I added my application project that will load the bundle, and which already has felix.jar in its build path. This as far as I understand will make the application and the APK bundle use the same felix.jar. (Instead of keeping different one in both, which makes Dalvik complains).

Therefore, I believe that the correct steps to create an APK android bundle, and then to load it to the framework would be:

  • 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)

Finally, is the final signed APK file my bundle that should be loaded by the framework? This seems odd because It is not even a jar file. Yes it is. As an APK, it is still a compatible JAR except that it contains dex files too.

The steps you have followed seem legit to me. According to my experience, it should have worked. Do you have any logtrace we can exploit? Knopflerfish console allows you to see the stacktrace when starting and stopping the bundles manually. It is extremely valuable here.

the bundle's code, especially the Activator class, MUST be in the same package as defined in AndroidManifest.xml AND the symbolic name of the bundle MUST be the package name as well. If these conditions are met then all of the classes will be correctly loaded. If not, it will result in seeing java.lang.NoClassDefFoundError on runtime

You don't have to make the symbolic name of the bundle and the bundle's code to be in the same package as the android application, as long as the export-package and the import-package in the manifest.mf is correctly set. You can use bndtools(http://bndtools.org) to help generate the correct manifest.mf automatically(for an android application, bndtool doesn't seem to work though. I have to use its obsolete one bnd.jar to do the job. bnd.jar can be downloaded here: http://www.java2s.com/Code/Jar/b/Downloadbndjar.htm)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!