android無framework Java應用開發

在android下,其實有另外的一類應用程序,他們用Java開發,但卻不使用android的應用框架,不包含android應用程序四大組件中的任何一個,幾乎就與咱們日常在PC機上開發的那些Java應用程序同樣。這裏,咱們來看一下,這樣的應用程序要如何實現。 java

最典型的無android framework的android Java程序就是兩個咱們常常會用到的工具,一個是monkey,另一個是am。咱們一般用前者來作monkey測試,而經常使用後者,來執行經過命令行啓動Activity等操做。這裏咱們也會以這兩個應用程序爲例,來研究android下frameworkless Java應用程序的開發方法。 android

要了解這些app的結構和實現,最簡單的方式則是直接來閱讀code和Android.mk 文件了。咱們來看一下monkey的code,在development/cmds/monkey/monkey下。首先,咱們能夠先來看一下這個project的目錄結構: shell

.. 01-Nov-2013 4 KiB

Android.mk 01-Nov-2013 423

example_script.txt 01-Nov-2013 731

MODULE_LICENSE_APACHE2 01-Nov-2013 0

monkey 01-Nov-2013 217

NOTICE 01-Nov-2013 10.4 KiB

README.NETWORK.txt 01-Nov-2013 4.1 KiB

src/ 01-Nov-2013 4 KiB

這個project根目錄下面的內容不是不少,src/目錄存放全部的源代碼文件,Android.mk用於編譯這個project,一個看上去有點奇怪的名爲"monkey"的文件,還有其餘一些對於咱們瞭解這樣的項目的建立方法而言可有可無的文件,好比readme,notice和license之類。接着咱們來看一下這個project Android.mk 文件的實現: app

# Copyright 2008 The Android Open Source Project
#
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := monkey
include $(BUILD_JAVA_LIBRARY)

################################################################
include $(CLEAR_VARS)
ALL_PREBUILT += $(TARGET_OUT)/bin/monkey
$(TARGET_OUT)/bin/monkey : $(LOCAL_PATH)/monkey | $(ACP)
$(transform-prebuilt-to-target)

這個Android.mk指導編譯系統在編譯時作了兩件事情,一是將project下全部的Java文件編譯爲一個Java library,LOCAL_MODULE的值爲monkey,也就意味着編譯的結果將會是一個名爲monkey.jar的文件,編譯出來的這個jar文件最終將位於設備的/system/framework/目錄下。另外,就是將當前目錄下那個名爲monkey的文件,作一個copy,最終這個文件將位於設備的/system/bin/目錄下。 框架

但monkey.jar和那個monkey文件分別是作什麼的,而它們到底又是一種什麼樣的關係呢?咱們日常下monkey命令時執行的又是哪個呢?咱們來看project根目錄下的那個monkey文件: less

# Script to start "monkey" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/monkey.jar
trap "" HUP
exec app_process $base/bin com.android.commands.monkey.Monkey $*

哦,原來這是一個shell腳本文件。在這個腳本文件中,就是設置環境變量,而後執行app_process本地應用程序。傳給腳本文件的全部參數,也都會直接傳遞給app_process命令。由此,便是說,當咱們執行monkey命令時,所直接執行的實際上是這個腳本文件,而後透過腳本文件,再來執行monkey Java應用程序。 dom

app_process大概就像是咱們PC平臺Java環境中的java命令同樣,便是Java虛擬機。咱們在設備上直接執行app_process這個命令,能夠看到這個app吐出以下的log: ide

root@cay:/ # app_process
Error: no class name or --zygote supplied.
Usage: app_process [java-options] cmd-dir start-class-name [options]
Illegal instruction (core dumped)

這個便是android下DVM虛擬機,以命令行的方式啓動的方法。由這個usage和前面那個shell腳本文件的實現,不難猜想,com.android.commands.monkey.Monkey應該是monkey這個Java app的main class。接着咱們來簡單看一下這個main class的實現: 工具

    /**
     * Command-line entry point.
     *
     * @param args The command-line arguments
     */
    public static void main(String[] args) {
        // Set the process name showing in "ps" or "top"
        Process.setArgV0("com.android.commands.monkey");
        int resultCode = (new Monkey()).run(args);
        System.exit(resultCode);
    }
    /**
     * Run the command!
     *
     * @param args The command-line arguments
     * @return Returns a posix-style result code. 0 for no error.
     */
    private int run(String[] args) {
        // Super-early debugger wait
        for (String s : args) {
            if ("--wait-dbg".equals(s)) {
                Debug.waitForDebugger();
            }
        }
        // Default values for some command-line options
        mVerbose = 0;
        mCount = 1000;
        mSeed = 0;
        mThrottle = 0;
        // prepare for command-line processing
        mArgs = args;
        mNextArg = 0;
        // set a positive value, indicating none of the factors is provided yet
        for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) {
            mFactors[i] = 1.0f;
        }
        if (!processOptions()) {
            return -1;
        }
        if (!loadPackageLists()) {
            return -1;
        }
        // now set up additional data in preparation for launch
        if (mMainCategories.size() == 0) {
            mMainCategories.add(Intent.CATEGORY_LAUNCHER);
            mMainCategories.add(Intent.CATEGORY_MONKEY);
        }
        if (mSeed == 0) {
            mSeed = System.currentTimeMillis() + System.identityHashCode(this);
        }

這些就徹底是常規Java 應用程序的寫法了。不過咱們也須要更正一下前面一些提法的錯誤之處。相似於monkey的這種Java應用程序,不必定徹底不會使用到android framework的任何組件,只不過這些應用程序的寫法,不一樣於常規android應用程序的寫法,卻是與常規的Java應用程序的寫法無異。若是這些應用程序要使用android framework提供的功能,則方法就與使用普通的jar文件無異。 測試

android下am命令的project結構與monkey大同小異,只不過,am這個project的路徑爲frameworks/base/cmds/am/。am的project結構:

.. 01-Nov-2013 4 KiB

am 01-Nov-2013 210

Android.mk 01-Nov-2013 354

MODULE_LICENSE_APACHE2 01-Nov-2013 0

NOTICE 01-Nov-2013 10.4 KiB

src/ 01-Nov-2013 4 KiB

am project Android.mk文件的實現:

# Copyright 2008 The Android Open Source Project
#
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := am
include $(BUILD_JAVA_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := am
LOCAL_SRC_FILES := am
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)

am腳本文件的實現:

#!/system/bin/sh
#
# 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 "$@"

Done.

相關文章
相關標籤/搜索