通过分析Android应用进程的创建启动流程,知道设置应用进程的名称是在http://androidxref.com/4.4_r1/xref/frameworks/base/core/java/android/app/ActivityThread.java#handleBindApplication

    private void handleBindApplication(AppBindData data) {        mBoundApplication = data;        mConfiguration = new Configuration(data.config);        mCompatConfiguration = new Configuration(data.config);        mProfiler = new Profiler();        mProfiler.profileFile = data.initProfileFile;        mProfiler.profileFd = data.initProfileFd;        mProfiler.autoStopProfiler = data.initAutoStopProfiler;        // send up app name; do this *before* waiting for debugger        Process.setArgV0(data.processName);        android.ddm.DdmHandleAppName.setAppName(data.processName,                                                UserHandle.myUserId());

所以反射调用即可修改进程名,ddm应该是ddms调试用的,这个不改应该也可以。

try {            Method setArgV0 = Process.class.getDeclaredMethod("setArgV0", String.class);            setArgV0.setAccessible(true);            setArgV0.invoke(null,"com.tencent.mm");        } catch (Throwable e) {            e.printStackTrace();        }

结合之前的linux修改进程名,

//字符串包括结尾符号\0不能超过16,而且这个只是改了proc/pid/stat/status中的字符串const char* new_name = "mytest";prctl(PR_SET_NAME, new_name);

或者这样可以改变ps、cmdline的进程名

/*gcc changetitle.c -o changetitle*/#include #include #include #include #include #include # define MAXLINE 2048extern char **environ;static char **g_main_Argv = NULL;    /* pointer to argument vector */static char *g_main_LastArgv = NULL;    /* end of argv */void setproctitle_init(int argc, char **argv, char **envp){    int i;    for (i = 0; envp[i] != NULL; i++) // calc envp num        continue;    environ = (char **) malloc(sizeof (char *) * (i + 1)); // malloc envp pointer    for (i = 0; envp[i] != NULL; i++)    {        environ[i] = malloc(sizeof(char) * strlen(envp[i]));        strcpy(environ[i], envp[i]);    }    environ[i] = NULL;    g_main_Argv = argv;    if (i > 0)        g_main_LastArgv = envp[i - 1] + strlen(envp[i - 1]);    else        g_main_LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);}void setproctitle(const char *fmt, ...){    char *p;    int i;    char buf[MAXLINE];    extern char **g_main_Argv;    extern char *g_main_LastArgv;    va_list ap;    p = buf;    va_start(ap, fmt);    vsprintf(p, fmt, ap);    va_end(ap);    i = strlen(buf);    if (i > g_main_LastArgv - g_main_Argv[0] - 2)    {        i = g_main_LastArgv - g_main_Argv[0] - 2;        buf[i] = '\0';    }    //修改argv[0]    (void) strcpy(g_main_Argv[0], buf);    p = &g_main_Argv[0][i];    while (p < g_main_LastArgv)        *p++ = '\0';    g_main_Argv[1] = NULL;        //调用prctl    prctl(PR_SET_NAME,buf);}int main(int argc, char *argv[]){    char argv_buf[MAXLINE] = {0}; // save argv paramters    int i;    for( i = 1; i < argc; i++)    {        strcat(argv_buf, argv[i]);        strcat(argv_buf, " ");    }        //修改argv[0]所指向的内存空间的内容    setproctitle_init(argc, argv, environ);        //调用prctl修改进程名    setproctitle("%[email protected]%s %s", "littlehann-prog", "ip", argv_buf);    for (i = 0; environ[i] != NULL; i++)        free(environ[i]);    getchar();    return 0;}

对比下Android是如果实现的,http://androidxref.com/4.4_r1/xref/frameworks/native/libs/binder/ProcessState.cpp#305

首先把进程名覆盖了mArgV第一个数组,之后也是调用

prctl(PR_SET_NAME, (unsigned long) new_name, 0, 0, 0);
// Global variablesint                 mArgC;const char* const*  mArgV;int                 mArgLen;void ProcessState::setArgV0(const char* txt){    if (mArgV != NULL) {        strncpy((char*)mArgV[0], txt, mArgLen);        set_process_name(txt);    }}
//http://androidxref.com/4.4_r1/xref/system/core/libcutils/process_name.c#37void set_process_name(const char* new_name) {#ifdef HAVE_ANDROID_OS    char  propBuf[PROPERTY_VALUE_MAX];#endif    if (new_name == NULL) {        return;    }    // We never free the old name. Someone else could be using it.    int len = strlen(new_name);    char* copy = (char*) malloc(len + 1);    strcpy(copy, new_name);    process_name = (const char*) copy;#if defined(HAVE_PRCTL)    if (len < 16) {        prctl(PR_SET_NAME, (unsigned long) new_name, 0, 0, 0);    } else {        prctl(PR_SET_NAME, (unsigned long) new_name + len - 15, 0, 0, 0);    }#endif#ifdef HAVE_ANDROID_OS    // If we know we are not running in the emulator, then return.    if (running_in_emulator == 0) {        return;    }    // If the "running_in_emulator" variable has not been initialized,    // then do it now.    if (running_in_emulator == -1) {        property_get("ro.kernel.qemu", propBuf, "");        if (propBuf[0] == '1') {            running_in_emulator = 1;        } else {            running_in_emulator = 0;            return;        }    }    // If the emulator was started with the "-trace file" command line option    // then we want to record the process name in the trace even if we are    // not currently tracing instructions (so that we will know the process    // name when we do start tracing instructions).  We do not need to execute    // this code if we are just running in the emulator without the "-trace"    // command line option, but we don't know that here and this function    // isn't called frequently enough to bother optimizing that case.    int fd = open(PROCESS_NAME_DEVICE, O_RDWR);    if (fd < 0)        return;    write(fd, process_name, strlen(process_name) + 1);    close(fd);#endif}

从名字上猜应该mArgV应该就是main函数接收的argv,我们知道Android应用进程其实都是fork自zygote,而zygote的可执行文件就是app_process

http://androidxref.com/4.4_r1/xref/frameworks/base/cmds/app_process/app_main.cpp#169

int main(int argc, char* const argv[]){#ifdef __arm__    /*     * b/7188322 - Temporarily revert to the compat memory layout     * to avoid breaking third party apps.     *     * THIS WILL GO AWAY IN A FUTURE ANDROID RELEASE.     *     * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=7dbaa466     * changes the kernel mapping from bottom up to top-down.     * This breaks some programs which improperly embed     * an out of date copy of Android's linker.     */    char value[PROPERTY_VALUE_MAX];    property_get("ro.kernel.qemu", value, "");    bool is_qemu = (strcmp(value, "1") == 0);    if ((getenv("NO_ADDR_COMPAT_LAYOUT_FIXUP") == NULL) && !is_qemu) {        int current = personality(0xFFFFFFFF);        if ((current & ADDR_COMPAT_LAYOUT) == 0) {            personality(current | ADDR_COMPAT_LAYOUT);            setenv("NO_ADDR_COMPAT_LAYOUT_FIXUP", "1", 1);            execv("/system/bin/app_process", argv);            return -1;        }    }    unsetenv("NO_ADDR_COMPAT_LAYOUT_FIXUP");#endif    // These are global variables in ProcessState.cpp    mArgC = argc;    mArgV = argv;    mArgLen = 0;    for (int i=0; i

所以其实Android修改进程名和Linux是一样的。

更多相关文章

  1. Android进程,任务,服务的信息
  2. Android进程与线程基本知识
  3. Android跨进程通信方式(IPC)解析
  4. Android多进程介绍与用法
  5. Android 双进程守护
  6. Android中ListView以及数组适配器(ArrayAdapter)的使用
  7. Android 面试经验 - Android 进程间的通信
  8. Android进程间通信--消息机制及IPC机制实现
  9. Android 8.1 zygote创建新应用进程

随机推荐

  1. 看不下去了!50多家组织致信谷歌要求允许用
  2. 【Android归纳】阿里笔试题之Android网络
  3. Android开发入门——Android(安卓)Studio
  4. Android(安卓)开发技巧-以友盟为例在Andr
  5. 如何实现服务器给android客户端主动推送
  6. Android(安卓)如何获取应用签名,微信需要
  7. Android单元测试/Ui测试+JaCoCo覆盖率统
  8. Android获取不同手机 自身存储和外置SD卡
  9. 以 Okhttp3源码 为例 ------ 图解 缓存机
  10. 【定制Android系统】Android(安卓)O 应用