3

私は現在、この問題に数日間取り組んだ後、頭をぶつけています。

私のネイティブ Android アプリは実行時にクラスをロードします。これは機能します。このチュートリアルに従って、アセット フォルダーから dexed jar を取得し、クラスをロードして静的メソッドを正常に呼び出しました。

ただし、実行すると...

env->FindClass("TheClass"); 

... Java 例外をスローします。

ここで、コードの関連ビット

//this works find and gives me a usable class
jclass shim_class = helper.LoadClassFromAssetsJar("test.jar","TheClass");
// this throws the exception    
jclass refound_shim_class = jni->FindClass("TheClass"); 

どんな助けも信じられないほど素晴らしいでしょう、乾杯の人々

4

1 に答える 1

1

さて、ここには本当にさまざまなものがありました。

最初に@Alex Cohnが言ったように、 「グローバル参照」を使用して簡単に実行できるクラスを保持する必要があるため、ジョブジェクト(またはjclassなど)が解放されるまで再割り当てされません。これは、Androidの以前のバージョンの一部にあったものであるため(私が見る限り)、この効果はスレッドローカルであると考えています

次に、ここでは退屈させませんが、アセット フォルダーから apk をロードするときにDexClassloaderを使用しているため (仕組みについてはこちらを参照)、これも保持する必要があります。FindClass は、システム クラスをロードするための独自のコンテキストでのみ機能します(これを行うと、独自のクラスをロードできます)

次に、各スレッドで apk のクラスを使用できるようにする必要があるため、各スレッドの JniEnv を作成するときに declassloader.loadclass を実行し、pthread_keyを使用してそれをキャッシュします。このようにして、どこでもクラスを取得し、キースレッド コールバックを介して割り当て解除が自動的に行われます。

とにかくそれだけで十分です。幸運を!

ps補足として、jniメソッドが未処理の例外をスローすると、他の呼び出しが機能するという保証はありません...一部は機能し、一部は機能せず、一部はsegfaultを引き起こします...したがって、Java側から自由にキャッチしますJava の悪意からネイティブ側を保護します。

于 2013-10-01T10:47:17.733 に答える