2012-10-21 15 views
7

Android上でJavaアプリケーションのコマンドライン版を実行する必要があります(それは自明ではないことは分かります)。DalvikVMのCLIがJNIライブラリで失敗する

私は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変数を設定しました。 LD_PRELOADでliblogをプリロードしようとしても、何も修正されませんでした。 dalvikvmが環境を設定する方法によって、何かが間違っている/異なっているようです。

+0

開始に使用したコマンドは何ですか...そこから開始します。 –

答えて

11

良い質問!私はこれを理解するために少し掘り下げなければならなかった。

libandroid_runtime.soには、dalvikvmコマンドを使用しているときにデフォルトでバインドされていない多数のJNIメソッドがあります。残念ながら、System.loadLibrary( "android_runtime")を実行することはできません。これは実際にすべてのネイティブメソッドをバインドしないためです。

しかし、いくつかの掘り下げの後では、内部で非公開で、com.android.internal.util.WithFrameworkというクラスが存在することは保証されていません。その目的はlibandroid_runtime.soをロードしてすべてをバインドすることですそのJNIメソッド。

はちょうどそうのように、dalvikvmコマンドで、クラス名の前にcom.android.internal.util.WithFrameworkを投げ、それを使用するには、次の

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

(注:原因WithFrameworkクラスに事前-Mデバイスにのみ動作し、 removed in M - ヘッドアップ@JaredRummler)

+0

私は自分のデバイスにWithFrameworkを持てるのに十分な運が良かったと思います。 – ApriOri

+0

ええ、それはほぼ確実にすべてのデバイスにあります。しかし、そこにいることは保証されておらず、将来的には遠ざかる/変わる可能性があります。 (非公開APIのように) – JesusFreke

+0

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

3

アンドロイドMの場合、私はこの方法が機能することを発見しました。あなたはandroid.utilのように、両方のSDKクラスを使用することができますので、

#!/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は、共有ライブラリがロードされたすべてのJavaクラスを使用してJavaコードを起動しているようだ:
はあなたのjar \ zipファイルを同行するhelloworld.shスクリプトを作成します。 .log.Logと "secret"ネイティブクラス、例えばActivityManagerNativeは、他のadbシェルコマンドで使用され、SDKには存在しません。

私が作成したJavaシェルコマンドでは、上記のクラスのリフレクションを使用する必要がありました。クローンを作成せずに正しくコンパイルしてAOSP全体を構築する方法がないようです。
誰かがもっと簡単な方法を知っている場合リフレクションなしでActivityManagerNativeをJavaコードで使用すると、私は助けに感謝します。

+0

私自身の質問に答えるには、使用することがわかっているクラスとメソッドのスタブ実装を作成してコンパイルすることができます – Tolstoyevsky

+0

app_processはデバイスへのルートアクセスを要求しますが、dalvikvmはない – francogrex

+0

OK?ほとんどのユーザーがadbシェルを使用してこれを実行するので、大きな問題のようには見えませんでした。それがあなたにとって問題なら、確かにdalvikvmを直接実行しようとすることができます。簡単な方法があれば、ここに投稿してください。 – Tolstoyevsky

関連する問題