14

sdCardに1つの.jarファイルがあります(dxツールを使用して、通常の.jarをdexにコンパイルしました..そうしないと、Androidは実行時に文句を言います)

使用したいクラスは実際にはアクティビティであり、「使用」とはインフレを意味します!

A) このようにクラスをロードすると、ロードされたクラスは親クラスのパッケージを親パッケージとして持つことに気付きました (コードを実行するもの: 例: jar ライブラリ内のクラスの実際のパッケージ: "com .something" & my-app-package: "com.wonderfull" -> ロードされたクラスは "com.wonderfull.com.something" にあります :) ) -> 再テスト: ライブラリと同じように元のパッケージを保持します

B)「最良の」シナリオでは、次のエラーが発生します。

アクティビティ ComponentInfo{com.appno2/com.appno1.futureLib.LibActivity} をインスタンス化できません: java.lang.ClassNotFoundException: ローダー dalvik.system.PathClassLoader の com.appno1.futureLib.LibActivity[/data/app/com.appno2-1 .apk]

C) マニフェストに、Activity (動的にロードされるもの) を次のように配置しました。

アクティビティ Android:name="com.appno1.futureLib.LibActivity" Android:label="@string/app_name" > /アクティビティ>

タイトルからの質問を繰り返します:sdCardのjarライブラリからActivityクラスを動的にロードして実際に使用することは可能ですか?

「なぜこれが欲しいの?」の場合 -ただの骨董品!+ 概念として: ユーザーが有効なライセンスを入力した直後に、アプリの実際のコードを (何かの jar の形で) ダウンロードする可能性

更新:-このアイデアはフラグメントで機能します(インポートされるクラスがフラグメントであることを意味します)

現在の結論: - 外部の .jar (たとえば、sdCard 上、またはインターネットからダウンロードするなど) にラメ Java クラスまたは Android UI 関連のクラスを含めることが可能であり、必要に応じてそれらを動的にロードします。そうそう: あなたはこの方法でこの活動を行うことはできません :( .. おそらくサービスでさえありません..

詳細情報 #1:実行時に Android アプリケーションからライブラリを動的にロードすることは可能ですか?

詳細情報 #2: http://android-developers.blogspot.ro/2011/07/custom-class-loading-in-dalvik.html

URLClassLoaderについて: これは機能します (DalvikClassLoader - ClassNotFoundException && を使用せずに、明らかに: このようにロードされたアクティビティをインフレートすることはできません)

File file = new File("/sdcard/myLib.jar");
File tmpDir = getDir("dex", 0);
ClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()}, this.getClass().getClassLoader());
DexClassLoader classloader = new DexClassLoader(file.getAbsolutePath(), tmpDir.getAbsolutePath(), null, loader);
Class<Object> classref = (Class<Object>) classloader.loadClass("packageInLib.ClassName");
Object myInstance = classref.getConstructor().newInstance();

Or instead of "loadClass"
Class<?> classref = Class.forName("packageInLib.ClassName", true, dalvikClassLoader);
4

2 に答える 2

1

同様のシナリオがあります。

AndroidManifest.xml に以下のコードを入れない場合

<activity android:name="com.appno1.futureLib.LibActivity" android:label="@string/app_name" > </activity>

U は以下のエラーになります。

10-21 17:04:25.860: E/AndroidRuntime(11050): Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {... ...}; have you declared this activity in your AndroidManifest.xml?

しかし、クライアント アプリケーションにアクティビティを登録すると、java.lang.ClassNotFoundException が発生します。

ローダーは、[/data/app/com.appno2-1.apk] で com.appno1.futureLib.LibActivity を検索しようとしました。明らかに、これは予期されていません。com.appno.futureLib.LibActivity は .jar ファイルにあると思います。

ローダーが .jar ファイル内の LibActivity を検索できるようにする方法があれば、問題が解決する可能性があります。

于 2012-10-21T09:36:54.770 に答える
0

JAR ファイルをスキャンして内容を確認し、URLClassloader を使用してクラスをロードできます。これは標準の Java (見たい場合は JavaSE 実装を持っています) ですが、Android API に含まれているので、問題なく動作すると思います。

developer.android.com の URLClassloader

基本的に、ClassLoader を取得します (ダーティ コードの警告!):

File file = new File("/sdcard/jars/myDynamicLib.jar");
ClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()}, this.getClass().getClassLoader());

メタデータ XML または何をロードするかを説明するものが必要です。

jar.getInputStream(jar.getEntry("myMetaData.xml"));

情報を読み込みます (情報を解析する方法は、使用する形式によって異なります。アプリに既に読み込まれている場合もあります)。これで、クラス名が取得されました。

そして今、ロードを試みます:

Class<?> classref = Class.forName(className, true, loader);
instance = (MyType) classref.getConstructor().newInstance();

繰り返しますが、私は Droid でそのようなことを試したことはありませんが、これでうまくいくと思います。

それで成り立っています。JAR ファイルへのパスと、ロードするクラスの名前が必要です。クラスローダーは、JAR からクラスを引き出します。

于 2012-10-21T16:51:05.423 に答える