この質問は、実行時にJavaバイトコードを動的に生成して実行中のDalvik VMにロードすることについて何度も質問(および回答)されていますが、実行時にdexファイル/バイトコードをアプリにロードする方法はありますか?
ありがとう
Dalvikチームは、ファーストクラスのランタイムコード生成ライブラリを構築したいと考えています。Androidのバグ6322として機能リクエストを追跡しています。残念ながら、パフォーマンスと正確性の問題のリストは非常に長いため、この問題に時間を費やす時期をお知らせすることはできません。
いくつかの選択肢がありますが、それらはすべていくつかの作業が必要になります。
アプリケーションを標準のJVMで実行し、そこですべてのランタイムコード生成を実行します。.classファイルをメモリからファイルにダンプしてから、それらのファイルに対してdxを実行します。非常に洗練されている場合は、このすべての作業をビルドに統合できます。
オープンソースのdxツールをプロジェクトライブラリとして含め、アプリケーション内から、場合によってはアプリケーションのクラスローダー内からプログラムで実行します。これにより、アプリケーションのバイナリが肥大化します。
実行時にdexファイル/バイトコードをアプリにロードする方法はありますか?
とを見てDexFile
くださいDexClassLoader
。
ASMとBCELを使用してJavaクラスを生成し、それらをDexファイルに変換しました。最後に、デバイスに動的にロードするjarファイルを作成しました。
あなたは私のコードをチェックすることができます:)
CまたはC++プログラム内で、DEXクラスをロードして呼び出す場合は、AndroidRuntime内でDalvik VMがどのように起動されるかを確認できます(例:frameworks / base / cmds / app_process / app_main.cpp:)。
status_t app_init(const char* className, int argc, const char* const argv[])
{
LOGV("Entered app_init()!\n");
AndroidRuntime* jr = AndroidRuntime::getRuntime();
jr->callMain(className, argc, argv);
LOGV("Exiting app_init()!\n");
return NO_ERROR;
}
「jr」AndroidRuntimeはすでに開始されているため、callMain()が呼び出されます。
status_t AndroidRuntime::callMain(
const char* className, int argc, const char* const argv[])
{
JNIEnv* env;
jclass clazz;
jmethodID methodId;
LOGD("Calling main entry %s", className);
env = getJNIEnv();
if (env == NULL)
return UNKNOWN_ERROR;
clazz = findClass(env, className);
if (clazz == NULL) {
LOGE("ERROR: could not find class '%s'\n", className);
return UNKNOWN_ERROR;
}
methodId = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
if (methodId == NULL) {
LOGE("ERROR: could not find method %s.main(String[])\n", className);
return UNKNOWN_ERROR;
}
<...>
env->CallStaticVoidMethod(clazz, methodId, strArray);
return NO_ERROR;
}
上記から、DEXクラスのコードがどのようにロードされ、CallStaticVoidMethod()がDEXコードの解釈を開始するかを確認できます。