2010-04-09 3 views

Trả lời

23

Nhóm Dalvik muốn xây dựng thư viện tạo mã thời gian chạy đầu tiên. Chúng tôi đang theo dõi yêu cầu tính năng dưới dạng Android bug 6322. Thật không may, chúng tôi có một danh sách rất dài về các vấn đề về hiệu suất và tính chính xác, vì vậy tôi không thể cung cấp cho bạn dòng thời gian khi chúng tôi dành thời gian cho vấn đề này.

Có một số lựa chọn thay thế, nhưng tất cả họ sẽ đưa một số công việc:

  • Chạy ứng dụng của bạn trên một JVM tiêu chuẩn và thực hiện tất cả các thế hệ mã thời gian chạy đó. Dump các tập tin .class từ bộ nhớ vào tập tin, và sau đó chạy dx trên những tập tin đó. Nếu bạn khá tinh vi, bạn có thể tích hợp tất cả công việc này vào bản dựng của mình.

  • Bao gồm công cụ dx nguồn mở làm thư viện dự án và thực thi nó theo chương trình từ bên trong ứng dụng của bạn, có thể trong trình nạp lớp của ứng dụng của bạn. Điều này sẽ bloat nhị phân của ứng dụng của bạn.

+1

Cảm ơn câu trả lời của bạn. Có điều gì ngăn tôi viết trình tạo mã của riêng tôi ngay bây giờ không? Tôi đã viết một cho. Net-> Flash và Net -> Net, và Dex giống như một chéo giữa các tệp Java .Class và Flash .ABC. Ngoài ra, cảm ơn liên kết. Tôi đã gắn dấu sao và thêm nhận xét (yêu cầu API của nó tương tự với DLR của .Net). –

+3

Bạn chắc chắn có thể viết trình tạo mã của riêng bạn ngay bây giờ. Nếu bạn cung cấp cho nó một giấy phép Apache, thậm chí tốt hơn! –

+3

Cập nhật: hãy xem dexmaker làm cho việc này dễ dàng: http://code.google.com/p/dexmaker/ –

5

là có cách nào để tải file dex/bytecode vào ứng dụng tại runtime?

Nhìn vào DexFileDexClassLoader.

+1

Trước đây về chủ đề này: http://stackoverflow.com/questions/1001944/android-remote-code-loading/2450049#2450049 – fadden

1

Nếu bên trong bất kỳ chương trình C hoặc C++, bạn muốn tải và gọi vào các lớp DEX, bạn có thể thấy cách Dalvik VM được bắt đầu, bên trong AndroidRuntime - cho các khuôn khổ dụ/cơ sở/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; 
} 

Như "jr" AndroidRuntime đã được bắt đầu, callMain() sẽ được gọi là:

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; 
} 

Từ trên, chúng ta có thể thấy cách mã các lớp DEX được nạp và CallStaticVoidMe thod() sẽ bắt đầu diễn giải các mã DEX.

2

Tôi đã sử dụng ASM và BCEL để tạo các lớp Java và sau đó tôi đã chuyển đổi chúng thành tệp Dex. Cuối cùng tôi đã tạo các tệp jar để tải động trên thiết bị.

Bạn có thể kiểm tra mã của tôi :)

https://github.com/sciruela/android