2012-10-21 25 views
7

Tôi cần chạy một phiên bản dòng lệnh của ứng dụng java trên Android (Vâng, tôi biết nó không phải là tầm thường).CLI trên DalvikVM không thành công trên JNI lib

Tôi đang cố gắng bắt đầu sử dụng Dalvikvm, nó thực sự bắt đầu nhưng ở đâu đó sau mã của tôi không thành công vì nó bắt đầu sử dụng android.util.log và ném ngoại lệ này.

java.lang.UnsatisfiedLinkError: println_native 
    at android.util.Log.println_native(Native Method) 
    at android.util.Log.i(Log.java:159) 
    at org.slf4j.impl.AndroidLogger.info(AndroidLogger.java:151) 
    at org.gihon.client.TunnelingClient.<init>(TunnelingClient.java:62) 
    at org.gihon.client.CLI.main(CLI.java:95) 
    at dalvik.system.NativeStart.main(Native Method) 

Tôi đã thử đặt biến môi trường, tôi đặt biến LD_LIBRARY_PATH và BOOTCLASSPATH. Tôi thậm chí đã thử tải trước liblog với LD_PRELOAD nhưng không có gì cố định. Dường như có điều gì đó sai/khác với cách dalvikvm đặt môi trường.

+0

Lệnh bạn đã sử dụng để bắt đầu nó là gì ... bắt đầu ở đó. –

Trả lời

11

Câu hỏi hay! Tôi phải đào một chút để tìm ra điều này.

Có một loạt các phương pháp JNI trong libandroid_runtime.so không bị ràng buộc theo mặc định, khi bạn đang sử dụng lệnh dalvikvm. Thật không may, bạn không thể chỉ làm một System.loadLibrary ("android_runtime"), bởi vì điều này không thực sự ràng buộc tất cả các phương thức gốc.

Tuy nhiên, sau khi đào một số, hóa ra có một nội bộ, không công khai, không được bảo đảm ở đó có tên là com.android.internal.util.WithFramework, với mục đích là tải libandroid_runtime.so và ràng buộc tất cả các phương pháp JNI của nó.

Để sử dụng nó, chỉ cần ném com.android.internal.util.WithFramework trước tên lớp của bạn, trên lệnh dalvikvm, như vậy:

dalvikvm -cp /some/path/classes.dex com.android.internal.util.WithFramework my.example.cls "This is an argument" 

(Lưu ý: Đây chỉ hoạt động trên pre-M thiết bị, do lớp WithFramework là removed in M - cảm ơn những người đứng đầu lên @JaredRummler)

+0

Tôi đoán tôi đã đủ may mắn để có WithFramework trên thiết bị của mình và nó hoạt động. – ApriOri

+0

Vâng, nó gần như chắc chắn có trên tất cả các thiết bị. Nhưng nó không được bảo đảm ở đó, và có thể biến mất/thay đổi trong tương lai. (giống như bất kỳ api không công khai nào) – JesusFreke

+0

'System.load ("/system/lib/libandroid_runtime.so ");'? –

3

Đối với android M, tôi thấy phương pháp này hoạt động.
Tạo một kịch bản helloworld.sh đi cùng jar tập tin \ zip của bạn:

#!/system/bin/sh 
# Copied by example from am command 
base=/system 
export CLASSPATH=/path/to/your/jar/HelloWorld.jar 
exec app_process $base/bin HelloWorldMainClass "[email protected]" 

app_process dường như bắt đầu mã java của bạn với tất cả các lớp học java và libs chia sẻ nạp, vì vậy bạn có thể sử dụng cả hai lớp SDK như android.util .log.Log VÀ các lớp bản địa "bí mật", ví dụ ActivityManagerNative, được sử dụng trong các lệnh shell adb khác và không có trong SDK.

BTW, với lệnh java shell tôi đã tạo, tôi phải sử dụng sự phản chiếu cho các lớp ở trên, bởi vì dường như tôi không có cách nào để biên dịch đúng cách mà không nhân bản và xây dựng toàn bộ AOSP ...
Nếu ai đó biết một cách dễ dàng hơn để ví dụ sử dụng ActivityManagerNative trong mã java mà không có sự phản ánh, tôi sẽ đánh giá cao sự trợ giúp.

+0

Để trả lời câu hỏi của riêng tôi: bạn có thể tạo triển khai sơ khai cho các lớp và phương thức bạn biết bạn sẽ sử dụng và biên dịch với chúng – Tolstoyevsky

+0

app_process yêu cầu quyền truy cập root vào thiết bị trong khi dalvikvm không – francogrex

+0

OK? Nhìn thấy như hầu hết người dùng sẽ chạy điều này bằng cách sử dụng vỏ adb, nó không có vẻ giống như một vấn đề lớn với tôi. Nếu đó là một vấn đề cho bạn, bạn chắc chắn có thể thử chạy trực tiếp dalvikvm. Nếu bạn có một cách dễ dàng để làm điều đó, xin vui lòng gửi nó ở đây. – Tolstoyevsky

Các vấn đề liên quan