OSGI捆绑包中的Android活动

OSGI捆绑包中的Android活动,android,android-activity,osgi,apache-felix,osgi-bundle,Android,Android Activity,Osgi,Apache Felix,Osgi Bundle,我正在开发完全支持android的OSGI捆绑包。到目前为止,通过我前面的问题,我能够在OSGI包中使用android API。它很好用,我试过了。我正在使用Felix框架 然而,我现在的任务是制作一个OSGI捆绑包来进行android活动并启动该活动。我还需要这些活动来请求权限,所以我想我需要OSGI包中的AndroidManifest.xml 在做一项研究时,我只能找到一个人描述他实现这一目标的经历。不幸的是,他提到的步骤对我来说是模棱两可的 在他的问题中,他说: I have found

我正在开发完全支持android的OSGI捆绑包。到目前为止,通过我前面的问题,我能够在OSGI包中使用android API。它很好用,我试过了。我正在使用Felix框架

然而,我现在的任务是制作一个OSGI捆绑包来进行android活动并启动该活动。我还需要这些活动来请求权限,所以我想我需要OSGI包中的
AndroidManifest.xml

在做一项研究时,我只能找到一个人描述他实现这一目标的经历。不幸的是,他提到的步骤对我来说是模棱两可的

在他的问题中,他说:

I have found a way to start activities owned by android bundles:

•the android bundle MUST be an APK which can be created using Eclipse Android Project
•add a Reference Library entry to the project Build Path for your OSGi framework (in my case framework.jar)
•edit bundle.manifest describing the bundle. The file is not part of the APK but will be used on build
•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
•Use Android Tools > Export Unsigned Android Package
•copy bundle.manifest in the unsigned APK as META-INF/MANIFEST.MF
•sign the APK using whatever certificate you want
•install the signed APK like any standard android application. Installation is required in order to have the Activity resolved. Without this the activity won't resolve and the bundle will fail
•have the OSGi framework load the bundle APK
他说:

•edit bundle.manifest describing the bundle. The file is not part of the APK but will be used on build
我所做的只是创建一个android项目(APK)并遵循前两个步骤。但是在上面的第三步中,我找不到
“bundle.manifest”
来编辑它。它根本不在那里,所以他为什么说编辑它

另外,当我导出未签名的Android软件包时,我应该将清单文件从何处复制到何处

最后,最终签名的APK文件是框架应该加载的包吗?这看起来很奇怪,因为它甚至不是一个jar文件

如果这些步骤对我没有帮助,那么有人能把我引向正确的方向吗?多谢各位

更新:

没有人回答我的问题,所以我做了以下工作:

1-在我的android应用程序项目中(我正试图将其作为一个捆绑包),我将Activator类包含在AndroidManifest.xml中提到的同一个包中。 下面是我的
Activator.java
类:

package com.example.patient;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator {

    private static BundleContext context;

    static BundleContext getContext() {
        return context;
    }


    public void start(BundleContext bundleContext) throws Exception {
        Activator.context = bundleContext;

   //I WOULD LIKE TO START THE ACTIVITY HERE TO DISPLAY THE TOAST MESSAGE
        System.out.println("Android APK Bundle Started");

    }


    public void stop(BundleContext bundleContext) throws Exception {
        Activator.context = null;



    }

}
这是我的
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.patient"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.patient.View_Patient_File_Activity"
            android:label="View Patient File" >


        </activity>
        <activity
            android:name="com.example.patient.Enter_Patient_ID_Activity"
            android:label="View Patient File" >

                        <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>
        </activity>
    </application>

</manifest>
5-我使用命令行和jar签名器工具手动签名了未签名的副本。比如:

jarsigner -verbose -keystore /path_to_keystore/mykeystore.keystore my_application.apk my_keystore_alias 
6-我在我的电脑和我的标签上安装了签名副本

7-最后,我运行我的应用程序,让OSGI框架加载相同的签名apk文件

无使用,虽然捆绑包状态为活动状态,但我在activator start()方法中没有看到消息,这意味着我的捆绑包没有正确加载。我去哪里了? 请帮忙

更新日期:2013年11月25日

我确保正确执行步骤,现在我得到了以下信息:

11-25 17:54:08.600: W/System.err(2714): org.osgi.framework.BundleException: Not found: com.example.patient.Activator
11-25 19:22:36.590: W/System.err(6652): Caused by: java.lang.ClassNotFoundException: com.example.patient.Activator not found by com.example.patient
这意味着我的bundle不包含Activator类,但我确信它确实包含。有什么不对劲吗

更新日期:2013年11月26日

我用WinZip打开了签名的APK。我注意到,与我以前构建的包不同,签名的APK不包含包括“Activator.class”在内的.class文件,因此我复制了包含项目所有.class文件的com目录,并将其粘贴到签名的APK中。接下来,我再次签署了APK。现在,当我安装APK时,我得到以下日志,其中包含许多错误:

11-25 23:16:25.651: D/dalvikvm(5617): DexOpt: --- BEGIN 'bundle.jar' (bootstrap=0) ---
11-25 23:16:26.271: D/dalvikvm(5617): DexOpt: --- END 'bundle.jar' (success) ---
11-25 23:16:26.271: D/dalvikvm(5617): DEX prep '/sdcard/felix-cache-1472376252.tmp/bundle1/version0.0/bundle.jar': unzip in 102ms, rewrite 620ms
11-25 23:16:26.271: W/dalvikvm(5617): Class resolved by unexpected DEX: Lcom/example/patient/Activator;(0x4074fa08):0x18a7b8 ref [Lorg/osgi/framework/BundleActivator;] Lorg/osgi/framework/BundleActivator;(0x40714410):0xbd630
11-25 23:16:26.271: W/dalvikvm(5617): (Lcom/example/patient/Activator; had used a different Lorg/osgi/framework/BundleActivator; during pre-verification)
11-25 23:16:26.271: I/dalvikvm(5617): Failed resolving Lcom/example/patient/Activator; interface 902 'Lorg/osgi/framework/BundleActivator;'
11-25 23:16:26.271: W/dalvikvm(5617): Link of class 'Lcom/example/patient/Activator;' failed
11-25 23:16:26.271: E/dalvikvm(5617): ERROR: defineClass(0x4074fa08, com.example.patient.Activator, 0x4079d468, 0, 955, 0x4073e918)
11-25 23:16:26.271: E/Zaid Log(5617): Problem installing the bundle :s
11-25 23:16:26.271: W/System.err(5617): org.osgi.framework.BundleException: Activator start error in bundle com.example.patient [1].
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.Felix.activateBundle(Felix.java:2196)
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.Felix.startBundle(Felix.java:2064)
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:942)
11-25 23:16:26.271: W/System.err(5617):     at com.example.patient_application.MainActivity.onCreate(MainActivity.java:136)
11-25 23:16:26.271: W/System.err(5617):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
11-25 23:16:26.271: W/System.err(5617):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1715)
11-25 23:16:26.271: W/System.err(5617):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1767)
11-25 23:16:26.271: W/System.err(5617):     at android.app.ActivityThread.access$1500(ActivityThread.java:122)
11-25 23:16:26.271: W/System.err(5617):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1005)
11-25 23:16:26.271: W/System.err(5617):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-25 23:16:26.271: W/System.err(5617):     at android.os.Looper.loop(Looper.java:132)
11-25 23:16:26.271: W/System.err(5617):     at android.app.ActivityThread.main(ActivityThread.java:4028)
11-25 23:16:26.271: W/System.err(5617):     at java.lang.reflect.Method.invokeNative(Native Method)
11-25 23:16:26.271: W/System.err(5617):     at java.lang.reflect.Method.invoke(Method.java:491)
11-25 23:16:26.271: W/System.err(5617):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
11-25 23:16:26.271: W/System.err(5617):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
11-25 23:16:26.271: W/System.err(5617):     at dalvik.system.NativeStart.main(Native Method)
11-25 23:16:26.271: W/System.err(5617): Caused by: java.lang.UnsupportedOperationException: can't load this type of class file
11-25 23:16:26.271: W/System.err(5617):     at java.lang.VMClassLoader.defineClass(Native Method)
11-25 23:16:26.271: W/System.err(5617):     at java.lang.ClassLoader.defineClass(ClassLoader.java:319)
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2279)
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1501)
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
11-25 23:16:26.271: W/System.err(5617):     at java.lang.ClassLoader.loadClass(ClassLoader.java:500)
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1374)
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:4329)
11-25 23:16:26.271: W/System.err(5617):     at org.apache.felix.framework.Felix.activateBundle(Felix.java:2141)
11-25 23:16:26.271: W/System.err(5617):     ... 17 more
最后,最终签名的APK文件是框架应该加载的包吗?这看起来很奇怪,因为它甚至不是一个jar文件。是的。作为一个APK,它仍然是一个兼容的JAR,只是它也包含dex文件


你所采取的步骤对我来说似乎是合法的。根据我的经验,它应该是有效的。你有我们可以利用的日志跟踪吗?Knopflerfish控制台允许您在手动启动和停止捆绑包时查看stacktrace。它在这里非常有价值。

有两个问题,通过解决它们,我终于安装了我的APK捆绑包,并开始在Felix上使用

1-与OSGI捆绑包不同,最终签名的APK不包含
.class
文件。这就是为什么我得到:
未找到:com.example.patient.Activator
。通过手动将
com
目录从我的android项目复制到已签名的APK,然后再次签名,我成功地解决了这个问题

2.@slash33提到的第二步是:

•将参考库条目添加到OSGi框架的项目构建路径中

导致我出现以下错误:

 (Lcom/example/patient/Activator; had used a different Lorg/osgi/framework/BundleActivator; during pre-verification)
在post的帮助下,我简单地删除了对库的引用,并从构建路径中删除了
felix.jar
。然后我这样做了:Build Path->Configure Build Path->Projects,然后我添加了将加载捆绑包的应用程序项目,它的构建路径中已经有了
felix.jar
。据我所知,这将使应用程序和APK包使用相同的
felix.jar
。(而不是在两者中保留不同的一个,这让Dalvik抱怨)

因此,我认为创建APK android捆绑包并将其加载到框架中的正确步骤是:

  • 创建常规APK,例如通过创建EclipseAndroid项目
  • 通过以下方式使捆绑包使用与应用程序相同的OSGI框架库: 构建路径->配置构建路径->项目,然后添加将加载捆绑包的应用程序项目。您的应用程序项目应该在其构建路径中包含OSGI框架jar文件(在我的例子中是
    felix.jar
  • 创建描述捆绑包的捆绑包清单文件。您可以将其称为
    bundle.manifest
  • 假设您的应用程序包是
    com.acme.helloworld
    (该值由AndroidManifest.xml中的manifest:package设置),您的OSGI捆绑包的Activator类必须
    放在包
    com.acme.helloworld
    中,并且您必须
    在捆绑包清单中设置
    捆绑包符号name:com.acme.helloworld
    。如果不满足这些条件中的任何一个,那么将在运行时导致
    java.lang.NoClassDefFoundError
  • 使用Android工具>导出未签名的Android软件包
  • bundle.manifest
    作为
    META-INF/manifest.MF
    复制到生成的未签名APK的根目录中。您可以使用Winzip打开未签名的APK并添加文件夹
    META-INF
  • 签署APK usi
     (Lcom/example/patient/Activator; had used a different Lorg/osgi/framework/BundleActivator; during pre-verification)