android 虚拟机运用

http://hubingforever.blog.163.com/blog/static/17104057920126178427815/

基本Dalvik VM调用  

2012-07-17 08:06:39|  分类: 深入研究 |字号 订阅

中文原文: http://hi.baidu.com/seucrcr/item/ebd1b34879a168086cc2f078
英文原文: http://www.netmite.com/android/mydroid/2.0/dalvik/docs/hello-world.html
在android设备上,dalvik vm通常都被嵌入到android应用框架里执行,也可以直接运行vm,就像你要在你桌面系统运行虚拟机一样。
但是很多Android的 JNI 无法调用。因为Android的很多 JNI 其实是需要手动注册的。要想完美的解决该问题,请在shell控制台直接通过运行app_process程序启动一个JAVA程序。 关于 此的更多内容请参考《 如何在Android中启动JAVA程序
    在编译完java源码后,转换并整合.class文件到.dex文件然后将它push到设备。这儿是个简单的例子:
    

    
    
    
     
     
     
     
% echo 'class Foo {' \
> 'public static void main(String[] args) {' \
> 'System.out.println("Hello, world"); }}' > Foo . java
% javac Foo . java
% dx -- dex -- output = foo . jar Foo . class
% adb push foo . jar / sdcard
% adb shell dalvikvm - cp / sdcard / foo . jar Foo
Hello , world 
    -cp 选项设置了路径。adb shel的初始路径可能并不是你要的,最好指定绝对路径。
    dx命令接收了每个class的文件、目录或者jar结构列表,当--output文件名以.jar、.zip或者.apk结尾时,一个叫做classes.dex的文件就被创建并保存。
    运行adb shell davlikvm -help可获得更多命令行选项。
1、使用调试器
    你可以通过服从jdwp的调试器来调试独立的应用,有两种基本方法。
    一种是通过TCP,一种是通过DDMS。(CR:唔,前面看过了)
2、桌面编译
    dalvik vm也可以直接在桌面使用,事实上这更复杂,因为你没有建立环境的一些东西,本地库代码被用于支持核心dalvik库。
    首先:
. build/envsetup.sh
lunch sim-eng
    你可以看到
    

    
    
    
     
     
     
     
============================================
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 =
============================================
    这引导你为桌面vm进行编译,编译是基于glibc的。该模式仅仅为实验用,或许将来会更有用。
    你可能看到TARGET_BUILD_TYPE=debug或者 = release或者什么都没有,你只要改变lunch命令的参数就可以。
    其次,编译:
make
    当完成后,在桌面运行dalvik:
    

    
    
    
     
     
     
     
% dalvikvm
E / dalvikvm ( 19521 ): ERROR : must specify non - '.' bootclasspath
W / dalvikvm ( 19521 ): JNI_CreateJavaVM failed
Dalvik VM init failed ( check log file )
    为了运行,你必须指定指定引导程序的路径,指定放解压jar文件后dex数据的空间。可以这样做:
    

    
    
    
     
     
     
     
#!/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 $@
    准备dx的方式和前面一行:
    

    
    
    
     
     
     
     
% 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
    你可以获得参数的帮助通过以下的命令:

% ./rund -help

    这也可以显示vm可用选项参数。模拟“调试”环境有完整的additional assertion,使能检测功能(导致了vm变慢),但是也因此能测试。

    上述所有都是基于x86的,其他的架构还要考虑porting工作,如果libffi支持你的系统,工作量会比较小。


http://hubingforever.blog.163.com/blog/static/171040579201261665254201/

Android命令am简介  

2012-07-16 06:59:42|  分类: 深入研究 |字号 订阅

Android在shell中提供了 am 命令来发送Intent,它的源码为位于 frameworks/base/cmds/am.
它本身是用JAVA代码来实现的。
执行 am 命令其实是通过运行shell脚本 frameworks/base/cmds/am/am,然后在该脚本中运行 app_process 命令来启动am这个java程序的。
frameworks/base/cmds/am/am脚本文件如下:
      

      
      
      
       
       
       
       
# Script to start "am" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/am.jar
exec app_process $base/bin com.android.commands.am.Am "$@"
am命令语法如下
usage: am [subcommand] [options]

    start an Activity: am start [-D] [-W] <INTENT>
        -D: enable debugging
        -W: wait for launch to complete

    start a Service: am startservice <INTENT>

    send a broadcast Intent: am broadcast <INTENT>

    start an Instrumentation: am instrument [flags] <COMPONENT>
        -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT)
        -e <NAME> <VALUE>: set argument <NAME> to <VALUE>
        -p <FILE>: write profiling data to <FILE>
        -w: wait for instrumentation to finish before returning

    start profiling: am profile <PROCESS> start <FILE>
    stop profiling: am profile <PROCESS> stop

    start monitoring: am monitor [--gdb <port>]
        --gdb: start gdbserv on the given port at crash/ANR

    <INTENT> specifications include these flags:
        [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
        [-c <CATEGORY> [-c <CATEGORY>] ...]
        [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
        [--esn <EXTRA_KEY> ...]
        [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
        [-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
        [-n <COMPONENT>] [-f <FLAGS>]
        [--grant-read-uri-permission] [--grant-write-uri-permission]
        [--debug-log-resolution]
        [--activity-brought-to-front] [--activity-clear-top]
        [--activity-clear-when-task-reset] [--activity-exclude-from-recents]
        [--activity-launched-from-history] [--activity-multiple-task]
        [--activity-no-animation] [--activity-no-history]
        [--activity-no-user-action] [--activity-previous-is-top]
        [--activity-reorder-to-front] [--activity-reset-task-if-needed]
        [--activity-single-top]
        [--receiver-registered-only] [--receiver-replace-pending]
        [<URI>]
结束


http://hubingforever.blog.163.com/blog/static/17104057920126166411775/

如何在Android中启动JAVA程序  

2012-07-16 06:47:35|  分类: 深入研究 |字号 订阅

在Android中启动JAVA程序其实有很多种方式,现总结如下
一、在Android应用程序中发送 Intent启动Android应用程序
这个方式最简单,最常用。在此不在累述。关于Intent的更多内容请阅读《 Intent技术简介
二、shell控制台通过 am命令发送Intent来启动 Android应用程序
在Android的shell控制台通过am命令发送Intent来启动 Android应用程序
关于此的详细内容请参考《 Android命令am详解》
三、 shell控制台直接通过 davlikvm命令启动一个JAVA程序。
该方式有个天生的缺点,即在其中,很多Android的JNI无法调用。因为Android的很多JNI其实是需要手动注册的。
关于请参考《 基本Dalvik VM调用》
四、shell 控制台直接 通过运行 app_process 程序启动一个JAVA程序
app_process 程序中,他会对 Android的JNI进行手动注册的,能很好的使用Android的API,因此 通过运行 app_process 程序启动一个JAVA程序,是一个比较完美的方式。 app_process 程序是一个C程序,它的源码位于frameworks\base\cmds\app_process。
关于它的使用请参考 Android命令am详解 》以及shell脚本 frameworks\base\cmds\am\am和frameworks\base\cmds\pm\pm
am脚本文件如下:
      

      
      
      
       
       
       
       
# Script to start "am" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/am.jar
exec app_process $base/bin com.android.commands.am.Am "$@"
pm脚本文件如下:
        

        
        
        
         
         
         
         
# Script to start "pm" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/pm.jar
exec app_process $base/bin com.android.commands.pm.Pm "$@"
CLASSPATH 指定了你的程序的位置, com.android.commands.pm.Pm 则说明了程序的入口为 com.android.commands.pm.Pm ,即 入口函数 main()所在的 类, " $@ " 就是传递给main()函数的参数,只是这里 " $@ "本身又是个shell传入的参数而已
需要注意的是 CLASSPATH 中的文件必须是dalvik文件格式的,关于此的转换请参 基本Dalvik VM调用》
当然 CLASSPATH中的文件可以是apk文件,只是你的apk中至少应该有个拥有main()入口函数的类。


http://zhangcb666.blog.163.com/blog/static/46963529201242302824661/

Android源码编译jar到system/framework并在应用中调用  

2012-05-23 12:28:24|  分类: Android |字号 订阅

Android源码编译jar到system/framework并在应用中调用

1.       Java工程下添加Android.mk文件,内容如:

##build to jar

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

 

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under,src)

 

LOCAL_MODULE := com.test.manager

LOCAL_CERTIFICATE := platform

 

include $(BUILD_JAVA_LIBRARY)

   

##cp com.test.manager to system/etc/permission 这里是把com.test.manager.xml拷贝到/system/etc/permission文件中

include $(CLEAR_VARS)

LOCAL_MODULE := com.test.manager.xml

LOCAL_MODULE_TAGS := optional

 

LOCAL_MODULE_CLASS :=ETC

#this will install the file in /system/etc/premission

LOCAL_MODULE_PATH :=$(TARGET_OUT_ETC)/permissions

LOCAL_SRC_FILES :=$(LOCAL_MODULE)

include $(BUILD_PREBUILT)

 

2.       在工程根目录下添加com.test.manager.xml文件

<?xml version="1.0" encoding="utf-8"?>

<permissions>

    <library name="com.test.manager"

            file="/system/framwork/com.test.manager.jar"/>

</permissions>

3.       调用

1> 在调用Jar的工程中添加

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

 

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under,src)

 

LOCAL_JAVA_LIBRARIES := com.test.manager #引入jar

   

LOCAL_PACKAGE_NAME := Test

LOCAL_CERTIFICATE := platform

include $(BUILD_PACKAGE)

 

2>在工程的AndroidManifest.xml文件的<application>中加入

<uses-library android:name="com.test.manager"/>

 

http://disanji.net/2011/01/22/android-jar/

Android下编译自己的库文件jar并在应用中调用

来自  flysolo
2011年 1月 22日
4,188 次阅读 评论 (0)

主要为了解决如下问题:
项目中使用了Android未公开的API,在Eclipse下会有红叉显示。
不同的项目抽出相同部分的代码共用。

必需的前提条件:
需要有Android源代码,编译的库文件主要是封装未公开API或者共用代码。

工程1:Java库文件工程

该工程最终会生成以jar结尾的Java库文件,并会被安装到设备的以下目录:
/system/framework/
另外还会安装相关库文件的说明文件,使系统能够找到库文件:
/system/etc/permissions/

1、建立工程
在Eclipse下新建一个空的Java工程。
在工程的
Java Build Path -> Libraries
下,导入Android的SDK中的 android.jar 库。
为工程创建相应的包和java文件。
下面假设包路径为 com.mytest.lib,最终生成的库为 mylib.jar。

2、为工程添加注册文件
在库文件工程的根目录下创建以下文件:
<permission xml file name>.xml
该文件是用来向系统注册库用的,名称可以自己定,在下面假设该文件为 mylibxml.xml。
在文件中加入以下内容:

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?> <permissions> <library  name="com.mytest.lib" file="/system/framework/mylib.jar"  /> </permissions>

其中的 library 用于将其下的 name 和 file 两个属性关联起来,name 的值后边会用到。
这里的 name 指定为工程的包名。
这里的 file 指定为库文件的存放路径,应该是:
/system/framework/<jar file name>.jar

3、为工程添加makefile文件:
在库文件工程的根目录下创建以下文件:
Android.mk
该文件是用来编译工程的,名称固定。
在文件中加入以下内容:
LOCAL_PATH:= $(call my-dir)
#MAKE_JAR
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := mylib
include $(BUILD_JAVA_LIBRARY)
#MAKE_XML
include $(CLEAR_VARS)
LOCAL_MODULE := mylibxml.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
LOCAL_SRC_FILES := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)
其中,MAKE_JAR 部分的 LOCAL_MODULE 部分指定为想要生成的库文件的名字,
需要与 .xml 文件中的 library 下的 file 部分一致。
其中,MAKE_XML 部分的 LOCAL_MODULE 部分指定为用于注册库的 .xml 文件。

4、生成应用程序可用的库文件
此时的工程,如果使用了未公开的API的话,在eclipse下应该是有红叉的。
这些错误不用管,只需要保证程序在Android的源码下能够编译通过即可。
将工程的java文件以及 .xml 和 .mk 按照目录结构拷贝到以下目录:
<Android source folder>/packages/apps/<project name>/
运行以下命令:
$ cd <Android source folder>
$ . ./build/envsetup.sh
$ mmm packages/apps/<project name>
将会生成一个 .jar 文件和一个 .xml 文件。
以上两个文件是应用程序在运行时需要用到的。
调试应用前,需要将两个文件拷贝到设备的相应目录上去:
.jar 文件:/system/framework/
.xml 文件:/system/etc/permissions/
拷贝到设备使用以下命令:
$ sudo adb push <.jar or .xml file path> <path in device>
拷贝完以后需要重启设备。

5、生成在Eclipse可以引用的库文件
在源码下编译的 .jar 文件在Eclipse中是不能使用的,需要单独生成。
在Eclipse下选中工程根目录,选择文件菜单中的导出Export,然后选择jar类型。
导出为jar文件时,只需要选中相应的java文件即可。
这样生成的jar文件仅仅供应用程序在Eclipse下使用,除非是以下情况:
库文件没有使用非公开的API,并且,
应用本身在Eclipse下编译就能够使用,不需要到源码下编译。
暂且为该文件命名为mylibtemp.jar

工程2:Android应用工程

1、建立工程
新建一个Android工程。
在工程的
Java Build Path -> Libraries
下,导入 mylibtemp.jar 库。
使用 mylibtemp.jar 中的类编写代码。
下面假设最后生成的应用程序文件为 myapp.apk。

2、编辑AndroidManifest.xml文件
编辑工程根目录下的 AndroidManifest.xml 文件。
在 application 下添加以下内容:

1
2
3
<uses-library android:name="com.mytest.lib"> </uses-library>

其中的 :name 表示所引用的库文件的包名。
其与库工程的 .xml 文件中的 name 应该是一致的。
这样在应用运行时就能够找到相应的 .jar 文件了。
如果引用了多个库,需要添加多个 uses-library 标签。

3、为工程添加makefile文件:
在库文件工程的根目录下创建以下文件:
Android.mk
该文件是用来编译工程的,名称固定。
在文件中加入以下内容:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_LIBRARIES := mylib
LOCAL_PACKAGE_NAME := myapp
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)
其中的 LOCAL_JAVA_LIBRARIES 表示程序会用到的库文件。
其名成与库工程下的 .mk 文件中 MAKE_JAR 部分下的 LOCAL_MODULE 应该是一致的。
其中的 LOCAL_PACKAGE_NAME 表示应用最后生成的名称。

4、编译应用程序
将工程的 src、res、assets 文件夹以及文件:
Android.mk 和 AndroidManifest.xml
按照目录结构拷贝到以下目录:
<Android source folder>/packages/apps/<project name>/
引用的 .jar 库文件并不需要。
运行以下命令:
$ cd <Android source folder>
$ . ./build/envsetup.sh
$ mmm packages/apps/<project name>
将会生成一个 .apk 文件。
运行以下命令将应用安装到设备:
$ sudo adb install [-r] <apk file path>

原文作者:不详,如果看见请联系我们~

原文链接:http://blog.csdn.net/ameyume/archive/2010/12/05/6055948.aspx


你可能感兴趣的:(android 虚拟机运用)