我正在尝试一些不同寻常的事情,所以我对遇到困难并不感到惊讶。
我想在Android平板电脑上使用Ubuntu chroot
作为UNIX CLI IDE,用于各种软件开发。由于我正在使用Android设备,我很好奇是否可以针对SDK构建Android代码,dx
(Dalvik eXchange编译器)编译的字节码,复制到SD卡,并使用dalvikvm
执行
'hello world'测试(没有Android API)工作正常,但我试过的少数Android API调用失败了java.lang.UnsatisfiedLinkError
。我尝试过的对API的调用似乎调用了Dalvik在运行时找不到的(可能是JNI)本机方法:
java.lang.UnsatisfiedLinkError: No implementation found for boolean android.os.SystemProperties.native_get_boolean(java.lang.String, boolean) (tried Java_android_os_SystemProperties_native_1get_1boolean and Java_android_os_SystemProperties_native_1get_1boolean__Ljava_lang_String_2Z)
at android.os.SystemProperties.native_get_boolean(Native Method)
at android.os.SystemProperties.getBoolean(SystemProperties.java:114)
at android.text.TextUtils.<clinit>(TextUtils.java:1919)
at android.media.AudioAttributes$Builder.build(AudioAttributes.java:337)
at android.media.AudioRecord.<init>(AudioRecord.java:233)
at AltTest.main(alttest.java:34)
对于一个具体的例子,我尝试了以下代码,比如test.java
:
import android.media.AudioRecord;
class APITest {
public static void main(String[] args) {
System.out.println("Hello, world!");
// compiles, 'dx'ifies, and runs up this this point
int apiMinimumBufferSize = AudioRecord.getMinBufferSize(44100,16,2);
System.out.println("Your audio sample buffer must be at least " + apiMinimumBufferSize + " bytes.");
}
}
使用以下内容编译为APITest.class
:
root@localhost:~/projects/test# CLASSPATH=/root/android-sdk-linux/platforms/android-21/android.jar javac test.java
dx
指明分数:
root@localhost:~/projects/test# /root/android-sdk-linux/build-tools/25.0.0/dx --dex --output=test.dex APITest.class
请注意,由于chroot
依赖关系,我们不希望APITest.class在android.jar
java环境中执行:
root@localhost:~/projects/test# java -cp ".:/root/android-sdk-linux/platforms/android-21/android.jar" APITest
Hello, world!
Exception in thread "main" java.lang.RuntimeException: Stub!
at android.media.AudioRecord.getMinBufferSize(AudioRecord.java:21)
at APITest.main(test.java:9)
但是,如果我们放置dx
ified构建的副本,我们可以从非chroot
ed android环境中看到它:
root@localhost:~/projects/test# cp test.dex /mnt/android_root/sdcard
然后我们可以尝试在正在运行的Android机器上执行dalvikvm
中的代码:
[non-root-user]@[product_ID]:/ # su
root@[product_ID]:/ # cd sdcard
root@[product_ID]:/sdcard # dalvikvm -cp test.dex APITest
Hello, world!
java.lang.UnsatisfiedLinkError: No implementation found for int android.media.AudioRecord.native_get_min_buff_size(int, int, int) (tried Java_android_media_AudioRecord_native_1get_1min_1buff_1size and Java_android_media_AudioRecord_native_1get_1min_1buff_1size__III)
at android.media.AudioRecord.native_get_min_buff_size(Native Method)
at android.media.AudioRecord.getMinBufferSize(AudioRecord.java:592)
at APITest.main(test.java:9)
我已经扫描了本机android文件系统中的所有lib*.so
文件(例如'/ system / lib'和'/ vendor / lib'),以查找看起来像dalvikvm
的方法名称的动态符号正在寻找和其他可能的“DLL入口点”基于我对JNI的模糊知识。我不知道到底在找什么。到目前为止,我只发现了潜在相关方法的随机散射。
我尝试在dalvikvm
下运行strace
(我从chroot
小心地解放了,所以我可以在原生Android环境中针对shell命令运行它)。我对系统调用流量的阅读是,除了阅读/system/vendor
中的许多库之外,dalvikvm
几乎没有提示它预期那些本机实现的位置。
我有一个想法是弄清楚如何让dalvikvm
告诉我它在哪里找到了原生实现。使用Ruboto IRB
,可以调用Android API方法,其中许多方法调用本机实现。如果在Dalvik中有可用的内省,我知道如何调用它,或者我知道如何将调试设备连接到已经由Android GUI激活的正在运行的进程,或者我知道如何调用Android GUI应用程序由Terminal Emulator
应用程序提供的CLI,我可以想象尝试类似的东西。
我还想象拆解一个正在运行的应用程序来研究各部分之间的相互关系,并尝试在Android生态系统中支持实用Dalvik代码的构建或运行时要求。
我的大多数想法都有点“蓝天”,从一个无知的位置进入一个开放的研究问题。我相信我会学到很多,但我可能需要很长时间才能找到前进的方法。
而且,所以,我希望有相关经验的人可以优雅地告诉我他们对我所犯的错误以及如何解决这些错误的了解。
所以,要从终端运行一些Android代码:
上面详述的临时构建过程中我缺少什么?
或者,我在运行时从执行上下文中遗漏了什么?
谢谢!