3

Android を完全にサポートする OSGI バンドルの開発に取り組んでいます。これまでの質問では、OSGI バンドル内で Android API を使用できました。それはうまく動作し、試してみました。Felix フレームワークを使用しています。

ただし、OSGIバンドルを作成してAndroidアクティビティを作成し、そのアクティビティを開始するという使命に固執しています。また、これらのアクティビティがパーミッションをリクエストできるようにする必要があるためAndroidManifest.xml、OSGI バンドルに が必要になると思います。

調査を行っているときに、これを達成した経験を説明している人を 1 人だけ見つけることができました。残念ながら、彼が言及した手順は私にはあいまいです。

彼の質問「OSGIの完全な Android サポート」で、彼が言ったことは次のとおりです。

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) を作成し、最初の 2 つの手順に従うことだけでした。しかし、上記の 3 番目のステップでは、"bundle.manifest"編集することができませんでした。まったく存在しないのに、なぜ彼はそれを編集すると言うのですか?

また、Export Unsigned Android Packageどこからどこにマニフェストファイルをコピーすればよいですか?

最後に、最終的に署名された 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>

2- OSGi フレームワーク (felix.jar) のプロジェクト ビルド パスに参照ライブラリ エントリを追加しました。

3- Android ツールを使用してプロジェクトの署名なしのコピーを生成しました。

4- という署名のないコピーのルート ディレクトリにフォルダーを追加し、META-INFそのフォルダー内に というファイルを追加しましたMANIFEST.MF。以下はそのファイルの内容です。

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Patient
Bundle-SymbolicName: com.example.patient
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.example.patient.Activator
Import-Package: org.osgi.framework;version="1.3.0"
Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.0

5-コマンドラインとjar署名ツールを使用して、署名されていないコピーに手動で署名しました. 何かのようなもの:

jarsigner -verbose -keystore /path_to_keystore/mykeystore.keystore my_application.apk my_keystore_alias 

6- 署名済みのコピーを PC とタブにインストールしました。

7- 最後に、アプリケーションを実行し、OSGI フレームワークに同じ署名済み apk ファイルをロードさせます。

NO USE、バンドルのステータスはアクティブですが、アクティベーターの 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

私のバンドルには 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
4

3 に答える 3

1

2 つの問題がありましたが、それらを解決することで、最終的に APK バンドルをインストールして Felix を開始することができました。

1- OSGI バンドルとは異なり、最終的に署名された APK には.classファイルが含まれていません。それが私が得ていた理由です:Not found: com.example.patient.Activator。Android プロジェクトから署名付き APK にディレクトリを手動でコピーし、com再度署名することで、この問題を解決できました。

2- @ slash33が言及した 2 番目のステップは次のとおりです。

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

次のエラーが発生していました:

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

この投稿の助けを借りて、ライブラリへの参照を削除felix.jarし、ビルド パスから削除しました。次に、ビルド パス -> ビルド パスの構成 -> プロジェクトを実行し、バンドルをロードするアプリケーション プロジェクトを追加しました。これは既にfelix.jarビルド パスに含まれています。私が理解している限り、これにより、アプリケーションと APK バンドルが同じ を使用するようになりますfelix.jar。(両方で異なるものを保持する代わりに、Dalvikが文句を言います)。

したがって、APK Android バンドルを作成し、それをフレームワークにロードする正しい手順は次のようになると思います。

  • Eclipse Android プロジェクトを作成するなどして、通常の APK を作成します。
  • アプリケーションで使用されているのと同じ OSGI フレームワーク ライブラリをバンドルで使用するには、[ビルド パス] -> [ビルド パスの構成] -> [プロジェクト] を選択し、バンドルをロードするアプリケーション プロジェクトを追加します。アプリケーション プロジェクトのビルド パス (私の場合は ) には、OSGI フレームワークの jar ファイルが含まれている必要がありますfelix.jar
  • バンドルを説明するバンドル マニフェスト ファイルを作成します。あなたはそれを呼び出すことができますbundle.manifest
  • アプリケーション パッケージがcom.acme.helloworld(この値は AndroidManifest.xml の manifest:package で設定されている) 場合、OSGI バンドルの Activator クラスをパッケージに配置する必要があり、バンドル マニフェストに設定する必要com.acme.helloworldがあります。これらの条件のいずれかが満たされない場合、実行時になります。Bundle-SymbolicName: com.acme.helloworldjava.lang.NoClassDefFoundError
  • Android ツールを使用する> 署名されていない Android パッケージをエクスポートする
  • bundle.manifest生成された署名なし APK のルート ディレクトリに としてコピーしMETA-INF/MANIFEST.MFます。Winzip を使用して署名されていない APK を開き、フォルダーを追加できますMETA-INF
  • 次のコマンドを使用して APK に署名します jarsigner -verbose -keystore /path_to_keystore/mykeystore.keystore my_application.apk my_keystore_alias
  • Android プロジェクトのすべての.classファイルを含むディレクトリを、署名済み apk のルート ディレクトリにコピーします。私の場合:それはcomディレクトリです。
  • APK にもう一度署名します。
  • APK バンドルをインストールします。
  • OSGi フレームワークをロードして、APK バンドル (まったく同じ APK ファイル) を開始します。
于 2013-11-26T08:02:27.373 に答える
0

バンドルのコード、特に Activator クラスは、AndroidManifest.xml で定義されているものと同じパッケージに含まれている必要があり、バンドルのシンボリック名もパッケージ名である必要があります。これらの条件が満たされている場合、すべてのクラスが正しくロードされます。そうでない場合、実行時に java.lang.NoClassDefFoundError が表示されます。

manifest.mf の export-package と import-package が正しく設定されている限り、バンドルのシンボリック名とバンドルのコードを Android アプリケーションと同じパッケージにする必要はありません。bndtools( http://bndtools.org ) を使用して、正しい manifest.mf を自動的に生成することができます (Android アプリケーションの場合、bndtool は機能しないようです。 job.bnd.jar はここからダウンロードできます: http://www.java2s.com/Code/Jar/b/Downloadbndjar.htm )

于 2014-05-18T14:17:03.470 に答える
0

最後に、最終的に署名された APK ファイルは、フレームワークによって読み込まれるべき私のバンドルですか? jarファイルでさえないので、これは奇妙に思えます。はい、そうです。APK としては、dex ファイルも含まれていることを除いて、互換性のある JAR のままです。

あなたがたどった手順は、私には正当に思えます。私の経験によると、それはうまくいったはずです。悪用できるログトレースはありますか? Knopflerfish コンソールを使用すると、バンドルを手動で開始および停止するときにスタック トレースを確認できます。ここは非常に貴重です。

于 2013-11-25T11:19:11.043 に答える