• 通过system调用Am命令执行动作


    在底层代码中看到这样一条语句:

             system("/system/bin/sh -c \"am broadcast -a android.intent.action.AT_AIRPLANE_MODE --ez state true\"");

    system 这是干什么的啊??

             经google原来system是系统调用,执行一个系统命令。

            

      这里system加上其参数的意思:

        调用system,通过shell,执行可执行程序或者脚本am,

        发送broadcast Action为:android.intent.action.AT_AIRPLANE_MODE 广播参数--ez 键值对 state true……

            

             这样也可以啊,我原来以为android底层要主动和上层进行交互,就得通过socket等,原来这样也可以的,真是学习了。

            

    1 system命令

      system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed.

    During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.

      system()函数调用/bin/sh来执行参数指定的命令,/bin/sh 一般是一个软连接,指向某个具体的shell,比如bash,-c选项是告诉shell从字符串command中读取命令;

      在该command执行期间,SIGCHLD是被阻塞的,好比在说:hi,内核,这会不要给我送SIGCHLD信号,等我忙完再说;

      在该command执行期间,SIGINT和SIGQUIT是被忽略的,意思是进程收到这两个信号后没有任何动作。

            

      为了更好的理解system()函数返回值,需要了解其执行过程,实际上system()函数执行了三步操作:

        a.fork一个子进程;

        b.在子进程中调用exec函数去执行command;

        c.在父进程中调用wait去等待子进程结束。

     

        对于fork失败,system()函数返回-1。

      如果exec执行成功,也即command顺利执行完毕,则返回command通过exit或return返回的值。

      注意,command顺利执行不代表执行成功,比如command:"rm debuglog.txt",不管文件存不存在该command都顺利执行了

      如果exec执行失败,也即command没有顺利执行,比如被信号中断,或者command命令根本不存在,system()函数返回127.

      如果command为NULL,则system()函数返回非0值,一般为1.

     

    具体可参考这篇文章:

             http://my.oschina.net/renhc/blog/53580

            

    2 AM

             am的代码实现在\frameworks\base\cmds\am\目录下:

    \frameworks\base\cmds\am\am 这个就是放在system/bin/am:

      base=/system

      export CLASSPATH=$base/framework/am.jar

      exec app_process $base/bin com.android.commands.am.Am "$@"

            

      通过app_process创建执行com.android.commands.am.Am这样进程 $@传递所有参数给Am

        \frameworks\base\cmds\am\src

        \frameworks\base\cmds\am\Android.mk

      将编译java层Am为一个am.jar包,下面看一下Am的支持的功能。

             

    public static void main(String[] args) {
            try {
                (new Am()).run(args);
            } catch (IllegalArgumentException e) {
                showUsage();
            }
        }
        
        private void run(String[] args) throws Exception {
            ……
            //获取ActivityManagerService实例
            mAm = ActivityManagerNative.getDefault();
    
            mArgs = args;
            String op = args[0];
            mNextArg = 1;
            
            //Am所支持的命令 
            if (op.equals("start")) {
                runStart();
            } else if (op.equals("startservice")) {
                runStartService();
            } else if (op.equals("force-stop")) {
                runForceStop();
            } else if (op.equals("kill")) {
                runKill();
            } else if (op.equals("kill-all")) {
                runKillAll();
            } else if (op.equals("instrument")) {
                runInstrument();
            } else if (op.equals("broadcast")) {
                sendBroadcast();
            }
            …… //很多命令
        }

    看一下发送广播的命令:

    private void sendBroadcast() throws Exception {
            //解析发送广播的参数
            Intent intent = makeIntent(UserHandle.USER_ALL);
            IntentReceiver receiver = new IntentReceiver();
            
            //通过AMS发送广播
            mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false,
                    mUserId);
            receiver.waitForFinish();
        }

      所以Android 还有这样一个工具am,通过看showUsage,可以干很多事情的;

  • 相关阅读:
    浅析微服务全链路灰度解决方案
    作业帮在线业务 Kubernetes Serverless 虚拟节点大规模应用实践
    重磅发布 | Serverless 应用中心:Serverless 应用全生命周期管理平台
    你不知道的 HTTPS 压测
    应用实时监控服务 ARMS 4 月功能新鲜快报
    托管式服务网络:云原生时代的应用体系架构进化
    可观测|时序数据降采样在Prometheus实践复盘
    巧用API网关构建大型应用体系架构
    卓越工程实践之—前端高质量单测
    科普达人丨一文看懂阿里云的秘密武器“神龙架构”
  • 原文地址:https://www.cnblogs.com/bastard/p/3056182.html
Copyright © 2020-2023  润新知