2012-10-21 7 views
7

पर विफल रहता है मुझे एंड्रॉइड पर जावा एप्लिकेशन का कमांड लाइन संस्करण चलाने की आवश्यकता है (हाँ मुझे पता है कि यह छोटा नहीं है)।DalvikVM पर सीएलआई जेएनआई lib

मैं इसे Dalvikvm का उपयोग शुरू करने की कोशिश कर रहा हूं, यह वास्तव में शुरू होता है लेकिन कहीं बाद में मेरा कोड विफल रहता है क्योंकि यह android.util.log का उपयोग शुरू करता है और इस अपवाद को फेंकता है।

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) 

मैं वातावरण चर की स्थापना, मैं LD_LIBRARY_PATH और BOOTCLASSPATH चर सेट की कोशिश की। मैंने एलडी_PRELOAD के साथ liblog preloading भी कोशिश की लेकिन कुछ भी तय नहीं किया। ऐसा लगता है कि dalvikvm पर्यावरण सेट करने के तरीके के साथ कुछ गलत/अलग है।

+0

आप इसे शुरू करने के लिए उपयोग की जाने वाली कमांड क्या है ... वहां से शुरू करें। –

उत्तर

11

अच्छा सवाल! मुझे इसे समझने के लिए थोड़ा सा खोदना पड़ा।

libandroid_runtime.so में जेएनआई विधियों की एक बहुत सी चीजें हैं जो डिफ़ॉल्ट रूप से बाध्य नहीं होती हैं, जब आप dalvikvm कमांड का उपयोग कर रहे हैं। दुर्भाग्यवश, आप केवल System.loadLibrary ("android_runtime") नहीं कर सकते हैं, क्योंकि यह वास्तव में सभी मूल विधियों को बाध्य नहीं करता है।

हालांकि, कुछ खुदाई के बाद, यह पता चला है कि एक आंतरिक, गैर-सार्वजनिक है, कॉम.android.internal.util.SFramework नामक कक्षा होने की गारंटी नहीं है, जिसका उद्देश्य libandroid_runtime.so लोड करना है और सभी को बांधना है इसकी जेएनआई विधियों।

इसका इस्तेमाल के लिए, बस, अपने वर्ग के नाम के सामने com.android.internal.util.WithFramework फेंक, dalvikvm आदेश पर तो जैसे:

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

(नोट: पूर्व एम उपकरणों पर यह केवल काम करता है, WithFramework वर्ग की वजह से removed in M - @JaredRummler के सिर के लिए धन्यवाद)

+0

मुझे लगता है कि मैं भाग्यशाली था कि मेरे डिवाइस पर WithFramework है और यह काम करता है। – ApriOri

+0

हाँ, यह लगभग सभी उपकरणों पर निश्चित रूप से है। लेकिन यह वहां होने की गारंटी नहीं है, और भविष्य में दूर/बदल सकता है। (किसी भी गैर-सार्वजनिक एपीआई की तरह) – JesusFreke

+0

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

3

एंड्रॉइड एम के लिए, मुझे यह तरीका काम करने के लिए मिला। ,

#!/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 साझा libs लोड सभी जावा वर्गों के साथ अपने जावा कोड शुरू करने और करने लगता है तो आप android.util की तरह दोनों एसडीके कक्षाओं का उपयोग कर सकते हैं:
अपने जार \ ज़िप फ़ाइल साथ देने के लिए एक helloworld.sh स्क्रिप्ट बनाएं .log.Log और "गुप्त" मूल वर्ग, उदाहरण के लिए ActivityManagerNative, जिनका उपयोग अन्य एडीबी शैल कमांड में किया जाता है, और एसडीके में मौजूद नहीं हैं।

बीटीडब्लू, जावा शैल कमांड के लिए मैंने बनाया, मुझे उपरोक्त वर्गों के प्रति प्रतिबिंब का उपयोग करना पड़ा, क्योंकि ऐसा लगता है कि मुझे क्लोनिंग और पूरे एओएसपी के बिना ठीक से संकलन करने का कोई तरीका नहीं है ...
यदि कोई उदाहरण के लिए एक आसान तरीका जानता है प्रतिबिंब के बिना जावा कोड में ActivityManagerNative का उपयोग करें, मैं मदद की सराहना करता हूं।

+0

अपने स्वयं के प्रश्न का उत्तर देने के लिए: आप कक्षाओं और विधियों के लिए स्टब कार्यान्वयन बना सकते हैं जिन्हें आप जानते हैं कि आप उपयोग करेंगे, और उनके खिलाफ संकलन – Tolstoyevsky

+0

ऐप_प्रोसेस को डिवाइस तक रूट पहुंच की आवश्यकता होती है जबकि dalvikvm – francogrex

+0

ठीक है? यह देखते हुए कि अधिकांश उपयोगकर्ता एडीबी खोल का उपयोग करके इसे चलाएंगे, यह मेरे लिए बड़ी समस्या प्रतीत नहीं होता था। यदि यह आपके लिए एक समस्या है, तो आप निश्चित रूप से सीधे dalvikvm चलाने की कोशिश कर सकते हैं। यदि आपके पास ऐसा करने का एक आसान तरीका है, तो कृपया इसे यहां पोस्ट करें। – Tolstoyevsky