读了《深入理解android》卷一,发现了一点小问题,层层查看源码查资料,浅谈下此文。



   //源码目录 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java   /**     * Prepare the arguments and fork for the system server process.     */    private static boolean startSystemServer()            throws MethodAndArgsCaller, RuntimeException {        /* Hardcoded command line to start the system server */        String args[] = {            "--setuid=1000",            "--setgid=1000",            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",            "--capabilities=130104352,130104352",            "--runtime-init",            "--nice-name=system_server",            "com.android.server.SystemServer",        };        ZygoteConnection.Arguments parsedArgs = null;        int pid;        try {            parsedArgs = new ZygoteConnection.Arguments(args);            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);            /* Request to fork the system server process */            pid = Zygote.forkSystemServer(                    parsedArgs.uid, parsedArgs.gid,                    parsedArgs.gids,                    parsedArgs.debugFlags,                    null,                    parsedArgs.permittedCapabilities,                    parsedArgs.effectiveCapabilities);        } catch (IllegalArgumentException ex) {            throw new RuntimeException(ex);        }        /* For child process */        if (pid == 0) {            handleSystemServerProcess(parsedArgs);        }        return true;    }-------------------------------------------------------------------------------//源码目录 dalvik/vm/native/dalvik_system_Zygote.cpp/* native public static int forkSystemServer(int uid, int gid, *     int[] gids, int debugFlags, long permittedCapabilities, *     long effectiveCapabilities); */static void Dalvik_dalvik_system_Zygote_forkSystemServer(        const u4* args, JValue* pResult){    pid_t pid;    pid = forkAndSpecializeCommon(args, true);    /* The zygote process checks whether the child process has died or not. */    if (pid > 0) {        int status;        LOGI("System server process %d has been created", pid);        gDvm.systemServerPid = pid;        /* There is a slight window that the system server process has crashed         * but it went unnoticed because we haven't published its pid yet. So         * we recheck here just to make sure that all is well.         */        if (waitpid(pid, &status, WNOHANG) == pid) {            LOGE("System server process %d has died. Restarting Zygote!", pid);            kill(getpid(), SIGKILL);        }    }    RETURN_INT(pid);}//源码目录 dalvik/vm/native/dalvik_system_Zygote.cpp/* * Utility routine to fork zygote and specialize the child process. */static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer){    pid_t pid;    uid_t uid = (uid_t) args[0];    gid_t gid = (gid_t) args[1];    ArrayObject* gids = (ArrayObject *)args[2];    u4 debugFlags = args[3];    ArrayObject *rlimits = (ArrayObject *)args[4];    int64_t permittedCapabilities, effectiveCapabilities;    //被调用函数自行转换参数    if (isSystemServer) {        /*         * Don't use GET_ARG_LONG here for now.  gcc is generating code         * that uses register d8 as a temporary, and that's coming out         * scrambled in the child process.  b/3138621         */        //permittedCapabilities = GET_ARG_LONG(args, 5);        //effectiveCapabilities = GET_ARG_LONG(args, 7);        permittedCapabilities = args[5] | (int64_t) args[6] << 32;        effectiveCapabilities = args[7] | (int64_t) args[8] << 32;    } else {        permittedCapabilities = effectiveCapabilities = 0;    }    if (!gDvm.zygote) {        dvmThrowIllegalStateException(            "VM instance not started with -Xzygote");        return -1;    }    if (!dvmGcPreZygoteFork()) {        LOGE("pre-fork heap failed");        dvmAbort();    }    setSignalHandler();    dvmDumpLoaderStats("zygote");    pid = fork();    ...---------------------------------------------------------------------------------

forksystemserver参数不一致了呀,发现没有?原因何在?

/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * This uses the FFI (Foreign Function Interface) library to abstract away * the system-dependent stuff.  The FFI code is slower than a custom * assembly version, but has the distinct advantage of having been * written already for several platforms. */#include "Dalvik.h"#include "ffi.h"/* * Convert a signature type character to an FFI type. */static ffi_type* getFfiType(char sigType){    switch (sigType) {    case 'V': return &ffi_type_void;    case 'Z': return &ffi_type_uint8;    case 'B': return &ffi_type_sint8;    case 'C': return &ffi_type_uint16;    case 'S': return &ffi_type_sint16;    case 'I': return &ffi_type_sint32;    case 'F': return &ffi_type_float;    case 'J': return &ffi_type_sint64;    case 'D': return &ffi_type_double;    case '[':    case 'L': return &ffi_type_pointer;    default:        LOGE("bad ffitype 0x%02x", sigType);        dvmAbort();        return NULL;    }}/* * Call "func" with the specified arguments. * * The second argument to JNI native functions is either the object (the * "this" pointer) or, for static functions, a pointer to the class object. * The Dalvik instructions will push "this" into argv[0], but it's up to * us to insert the class object. * * Because there is no such thing in as a null "this" pointer, we use * the non-NULL state of "clazz" to determine whether or not it's static. * * For maximum efficiency we should compute the CIF once and save it with * the method.  However, this requires storing the data with every native * method.  Since the goal is to have custom assembly versions of this * on the platforms where performance matters, I'm recomputing the CIF on * every call. */void dvmPlatformInvoke(void* pEnv, ClassObject* clazz, int argInfo, int argc,    const u4* argv, const char* shorty, void* func, JValue* pReturn){    const int kMaxArgs = argc+2;    /* +1 for env, maybe +1 for clazz*/    ffi_cif cif;    ffi_type* types[kMaxArgs];    void* values[kMaxArgs];    ffi_type* retType;    char sigByte;    int srcArg, dstArg;    types[0] = &ffi_type_pointer;    values[0] = &pEnv;    types[1] = &ffi_type_pointer;    if (clazz != NULL) {        values[1] = &clazz;        srcArg = 0;    } else {        values[1] = (void*) argv++;        srcArg = 1;    }    dstArg = 2;    /*     * Scan the types out of the short signature.  Use them to fill out the     * "types" array.  Store the start address of the argument in "values".     */    retType = getFfiType(*shorty);    while ((sigByte = *++shorty) != '\0') {        types[dstArg] = getFfiType(sigByte);        values[dstArg++] = (void*) argv++;        if (sigByte == 'D' || sigByte == 'J')            argv++;    }    /*     * Prep the CIF (Call InterFace object).     */    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, dstArg, retType, types) != FFI_OK) {        LOGE("ffi_prep_cif failed");        dvmAbort();    }    ffi_call(&cif, FFI_FN(func), pReturn, values);}

在dalvik虚拟机执行native方法有两种,DalvikNativeFunc和DalvikBridgeFunc,头一种方法有虚拟机直接调用,用指针传递参数,很简洁,比如const u4*,需要时在被调用方法里自行转换参数,并不需要方法签名的帮助来转换参数,方法签名只用于标示重载函数,这些函数可以理解成虚拟机的一部分,设计时针对不同平台进行编码,会调用不同平台的系统函数。第二种jni调用了,从源码可知在调用时会加入env 和clazz参数 ,并根据方法签名转换参数。需要说明的是在jni调用方面 ffi方式一般用于未知平台。像arm和x86平台都用汇编实现了。












更多相关文章

  1. Android Studio sdk tools文件夹下文件缺失问题以及解决方法
  2. Android -- 加载大图片的方法
  3. [Android] Handler源码解析 (Java层)
  4. Android开发之fedora13下编译Android源码
  5. Xamarin 中开发Android实现全屏或者不显示标题栏的方法-宋兴柱
  6. Android 字体加粗的两种方法
  7. Android×××方法详解
  8. 【解决方法】ADT在线安装

随机推荐

  1. WifiManager类详解
  2. Mono 2.10.3 is released
  3. iOS to Android
  4. Kotlin for android developers
  5. TextUtils的使用
  6. Android(安卓)studio 升级3.0,butterknife
  7. Android(安卓)星星评价
  8. Ubuntu 14.05上编译KODI 17.4
  9. android中dom解析
  10. android:网络编程