217 lines
6.6 KiB
HTML
217 lines
6.6 KiB
HTML
<html>
|
|
<head>
|
|
<title>Basic Dalvik VM Invocation</title>
|
|
</head>
|
|
|
|
<body>
|
|
<h1>Basic Dalvik VM Invocation</h1>
|
|
|
|
<p>
|
|
On an Android device, the Dalvik virtual machine usually executes embedded
|
|
in the Android application framework. It's also possible to run it directly,
|
|
just as you would a virtual machine on your desktop system.
|
|
</p><p>
|
|
After compiling your Java language sources, convert and combine the .class
|
|
files into a DEX file, and push that to the device. Here's a simple example:
|
|
|
|
</p><p><code>
|
|
% <font color="green">echo 'class Foo {'\</font><br>
|
|
> <font color="green">'public static void main(String[] args) {'\</font><br>
|
|
> <font color="green">'System.out.println("Hello, world"); }}' > Foo.java</font><br>
|
|
% <font color="green">javac Foo.java</font><br>
|
|
% <font color="green">dx --dex --output=foo.jar Foo.class</font><br>
|
|
% <font color="green">adb push foo.jar /sdcard</font><br>
|
|
% <font color="green">adb shell dalvikvm -cp /sdcard/foo.jar Foo</font><br>
|
|
Hello, world
|
|
</code>
|
|
</p><p>
|
|
The <code>-cp</code> option sets the classpath. The initial directory
|
|
for <code>adb shell</code> may not be what you expect it to be, so it's
|
|
usually best to specify absolute pathnames.
|
|
|
|
</p><p>
|
|
The <code>dx</code> command accepts lists of individual class files,
|
|
directories, or Jar archives. When the <code>--output</code> filename
|
|
ends with <code>.jar</code>, <code>.zip</code>, or <code>.apk</code>,
|
|
a file called <code>classes.dex</code> is created and stored inside the
|
|
archive.
|
|
</p><p>
|
|
Run <code>adb shell dalvikvm -help</code> to see a list of command-line
|
|
options.
|
|
</p><p>
|
|
|
|
|
|
|
|
<h2>Using a debugger</h2>
|
|
|
|
<p>
|
|
You can debug stand-alone applications with any JDWP-compliant debugger.
|
|
There are two basic approaches.
|
|
</p><p>
|
|
The first way is to connect directly through TCP. Add, to the "dalvikvm"
|
|
invocation line above, an argument like:
|
|
</p><p>
|
|
<code> -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y</code>
|
|
</p><p>
|
|
This tells the VM to wait for a debugger to connect to it on TCP port 8000.
|
|
You need to tell adb to forward local port 8000 to device port 8000:
|
|
</p><p>
|
|
<code>% <font color="green">adb forward tcp:8000 tcp:8000</font></code>
|
|
</p><p>
|
|
and then connect to it with your favorite debugger (using <code>jdb</code>
|
|
as an example here):
|
|
</p><p>
|
|
<code>% <font color="green">jdb -attach localhost:8000</font></code>
|
|
</p><p>
|
|
When the debugger attaches, the VM will be in a suspended state. You can
|
|
set breakpoints and then tell it to continue.
|
|
|
|
|
|
</p><p>
|
|
You can also connect through DDMS, like you would for an Android application.
|
|
Add, to the "dalvikvm" command line:
|
|
</p><p>
|
|
<code> -agentlib:jdwp=transport=dt_android_adb,suspend=y,server=y</code>
|
|
</p><p>
|
|
Note the <code>transport</code> has changed, and you no longer need to
|
|
specify a TCP port number. When your application starts, it will appear
|
|
in DDMS, with "?" as the application name. Select it in DDMS, and connect
|
|
to it as usual, e.g.:
|
|
</p><p>
|
|
<code>% <font color="green">jdb -attach localhost:8700</font></code>
|
|
</p><p>
|
|
Because command-line applications don't include the client-side
|
|
DDM setup, features like thread monitoring and allocation tracking will not
|
|
be available in DDMS. It's strictly a debugger pass-through in this mode.
|
|
</p><p>
|
|
See <a href="debugger.html">Dalvik Debugger Support</a> for more information
|
|
about using debuggers with Dalvik.
|
|
|
|
|
|
|
|
<h2>Working with the desktop build</h2>
|
|
|
|
<!-- largely lifted from
|
|
http://groups.google.com/group/android-porting/browse_thread/thread/ab553116dbc960da/29167c58b3b49051#29167c58b3b49051
|
|
-->
|
|
|
|
<p>
|
|
The Dalvik VM can also be used directly on the desktop. This is somewhat
|
|
more complicated however, because you won't have certain things set up in
|
|
your environment, and several native code libraries are required to support
|
|
the core Dalvik libs.
|
|
</p><p>
|
|
Start with:
|
|
|
|
<pre>
|
|
. build/envsetup.sh
|
|
lunch sim-eng
|
|
</pre>
|
|
|
|
You should see something like:
|
|
|
|
<pre>
|
|
============================================
|
|
TARGET_PRODUCT=sim
|
|
TARGET_BUILD_VARIANT=eng
|
|
TARGET_SIMULATOR=true
|
|
TARGET_BUILD_TYPE=debug
|
|
TARGET_ARCH=x86
|
|
HOST_ARCH=x86
|
|
HOST_OS=linux
|
|
HOST_BUILD_TYPE=release
|
|
BUILD_ID=
|
|
============================================
|
|
</pre>
|
|
|
|
</p></p>
|
|
This configures you to build for the desktop, linking against glibc.
|
|
This mode is NOT recommended for anything but experimental use. It
|
|
may go away in the future.
|
|
</p></p>
|
|
You may see <code>TARGET_BUILD_TYPE=release</code> or <code>=debug</code>
|
|
or possibly nothing there at all. You may want to replace the
|
|
<code>lunch</code> command with
|
|
<code>choosecombo Simulator debug sim eng</code>.
|
|
</p></p>
|
|
Build the world (add a <code>-j4</code> if you have multiple cores):
|
|
|
|
<pre>
|
|
make
|
|
</pre>
|
|
|
|
</p></p>
|
|
When that completes, you have a working dalvikm on your desktop
|
|
machine:
|
|
|
|
<pre>
|
|
% dalvikvm
|
|
E/dalvikvm(19521): ERROR: must specify non-'.' bootclasspath
|
|
W/dalvikvm(19521): JNI_CreateJavaVM failed
|
|
Dalvik VM init failed (check log file)
|
|
</pre>
|
|
|
|
</p></p>
|
|
To actually do something, you need to specify the bootstrap class path
|
|
and give it a place to put DEX data that it uncompresses from jar
|
|
files. You can do that with a script like this:
|
|
|
|
<blockquote><pre>
|
|
#!/bin/sh
|
|
|
|
# base directory, at top of source tree; replace with absolute path
|
|
base=`pwd`
|
|
|
|
# configure root dir of interesting stuff
|
|
root=$base/out/debug/host/linux-x86/product/sim/system
|
|
export ANDROID_ROOT=$root
|
|
|
|
# configure bootclasspath
|
|
bootpath=$root/framework
|
|
export BOOTCLASSPATH=$bootpath/core.jar:$bootpath/ext.jar:$bootpath/framework.jar:$bootpath/android.policy.jar:$bootpath/services.jar
|
|
|
|
# this is where we create the dalvik-cache directory; make sure it exists
|
|
export ANDROID_DATA=/tmp/dalvik_$USER
|
|
mkdir -p $ANDROID_DATA/dalvik-cache
|
|
|
|
exec dalvikvm $@
|
|
</pre></blockquote>
|
|
|
|
</p></p>
|
|
The preparation with <code>dx</code> is the same as before:
|
|
|
|
<pre>
|
|
% cat > Foo.java
|
|
class Foo { public static void main(String[] args) {
|
|
System.out.println("Hello, world");
|
|
} }
|
|
(ctrl-D)
|
|
% javac Foo.java
|
|
% dx --dex --output=foo.jar Foo.class
|
|
% ./rund -cp foo.jar Foo
|
|
Hello, world
|
|
</pre>
|
|
|
|
As above, you can get some info about valid arguments like this:
|
|
|
|
<pre>
|
|
% ./rund -help
|
|
</pre>
|
|
|
|
</p></p>
|
|
This also shows what options the VM was configured with. The sim "debug"
|
|
build has all sorts of additional assertions and checks enabled,
|
|
which slows the VM down, but since this is just for experiments it
|
|
doesn't matter.
|
|
|
|
</p></p>
|
|
All of the above applies to x86 Linux. Anything else will likely
|
|
require a porting effort. If libffi supports your system, the amount of
|
|
work required should be minor.
|
|
|
|
</p></p>
|
|
<address>Copyright © 2009 The Android Open Source Project</address>
|
|
|
|
</body>
|
|
</html>
|