美文网首页
Android ActivityManagerService--

Android ActivityManagerService--

作者: DarcyZhou | 来源:发表于2023-11-05 08:46 被阅读0次

本文转载自:

本文基于Android 11.0源码分析

前言

  在Android系统中,可以用am命令来启动一个组件。例如,可以用下面的命令启动Camera:

am start -n com.android.camera/com.android.camera.Camera

1.am架构

  从代码实现上来说,在Android系统中,Android Framework层的各个service作为服务端,而使用者通过RPC(远程过程调用)调用这些服务,使用者就是Client端。

  从进程间通信角度来说,Android Framework层的各个service作为服务端,提供具体的功能;同时,应用程序为了访问这些service,需要通过binder机制与service进行通信,这些运行在app端的代码就是client端(诸如ActivityManagerProxy等各种服务代理)。

  具体到今天分析的am来说,am作为client端,与Framework的server端的AMS通过binder进行交互;从而实现AMS提供的各种功能,如图:

AMS18.PNG

(1)am的编译Android.bp

// frameworks/base/cmds/am/Android.bp
// Copyright 2008 The Android Open Source Project
//

cc_library_host_static {
    name: "libinstrumentation",
    srcs: ["**/*.proto"],
    cflags: ["-Wall", "-Werror"],
    proto: {
        type: "full",
        export_proto_headers: true,
    },
}

java_binary {
    name: "am",
    wrapper: "am",
    srcs: [
        "src/**/*.java",
        "proto/**/*.proto",
    ],
    proto: {
        plugin: "javastream",
    },
    static_libs: ["libprotobuf-java-lite"],
}

(2)源码路径

frameworks/base/cmds/am/

2.Am类相关代码的分析

2.1 Am类图

AMS19.PNG

说明(主要对Am类进行说明):

  1. Am类:即am命令的入口类,有main方法。Am是client端组件,拥有一个远程代理组建mAm;

  2. 数据成员mAm

  • mAm:Am类通过mAm来实现相关的功能,包括启动一个activity或service,发送一个广播等。mAm的真正实体类型是AcitivtyManagerProxy类型,因为mActivityManager是一个接口,无法实例化,而继承自mActivityManager的AcitivtyManagerProxy可以实例化。
  • mArgs:即am命令的参数;
  1. 方法
  • runStartService:启动一个service;
  • sendBroadcast:发送一个广播;

2.2 run方法的分析

  am是可执行程序,其对应的实现在Am.java中,当然有main方法。在main方法中,调用了run方法。main方法调用run,代码如下:

// frameworks/base/cmds/am/src/com/android/commands/am/Am.java
    public static void main(String[] args) {
        (new Am()).run(args);
    }

Am.java继承BaseCommand.java,而run()方法在BaseCommand.java中定义:

 // frameworks/base/core/java/com/android/internal/os/BaseCommand.java
    public void run(String[] args) {
        if (args.length < 1) {
            // 如果没有参数则显示信息
            onShowUsage(System.out);
            return;
        }

        mRawArgs = args;
        mArgs.init(null, null, null, null, args, 0);

        try {
            // 执行onRun()
            onRun();
        } catch (IllegalArgumentException e) {
            onShowUsage(System.err);
            System.err.println();
            System.err.println("Error: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace(System.err);
            System.exit(1);
        }
    }

回到Am.java中,它实现了onRun()方法:

// frameworks/base/cmds/am/src/com/android/commands/am/Am.java
    public void onRun() throws Exception {

        // 获取AMS服务
        mAm = ActivityManager.getService();
        if (mAm == null) {
            System.err.println(NO_SYSTEM_ERROR_CODE);
            throw new AndroidException("Can't connect to activity manager; is the system running?");
        }

        // 获取PKMS服务
        mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
        if (mPm == null) {
            System.err.println(NO_SYSTEM_ERROR_CODE);
            throw new AndroidException("Can't connect to package manager; is the system running?");
        }

        String op = nextArgRequired();

        if (op.equals("instrument")) {
            runInstrument();
        } else {
            // 调用此处
            runAmCmd(getRawArgs());
        }
    }
---------------------------------------------------------
    void runAmCmd(String[] args) throws AndroidException {
        final MyShellCallback cb = new MyShellCallback();
        try {
            mAm.asBinder().shellCommand(FileDescriptor.in, FileDescriptor.out, FileDescriptor.err,
                    args, cb, new ResultReceiver(null) { });
        } catch (RemoteException e) {
            System.err.println(NO_SYSTEM_ERROR_CODE);
            throw new AndroidException("Can't call activity manager; is the system running?");
        } finally {
            cb.mActive = false;
        }
    }

这里通过Binder通信,最后调用到AMS服务中:

// frameworks/base/core/java/android/os/Binder.java
    protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
            int flags) throws RemoteException {
        if (code == INTERFACE_TRANSACTION) {
            reply.writeString(getInterfaceDescriptor());
            return true;
        } else if (code == DUMP_TRANSACTION) {
            ParcelFileDescriptor fd = data.readFileDescriptor();
            String[] args = data.readStringArray();
            if (fd != null) {
                try {
                    dump(fd.getFileDescriptor(), args);
                } finally {
                    IoUtils.closeQuietly(fd);
                }
            }
            // Write the StrictMode header.
            if (reply != null) {
                reply.writeNoException();
            } else {
                StrictMode.clearGatheredViolations();
            }
            return true;
        } else if (code == SHELL_COMMAND_TRANSACTION) {
            ParcelFileDescriptor in = data.readFileDescriptor();
            ParcelFileDescriptor out = data.readFileDescriptor();
            ParcelFileDescriptor err = data.readFileDescriptor();
            String[] args = data.readStringArray();
            ShellCallback shellCallback = ShellCallback.CREATOR.createFromParcel(data);
            ResultReceiver resultReceiver = ResultReceiver.CREATOR.createFromParcel(data);
            try {
                if (out != null) {
                    shellCommand(in != null ? in.getFileDescriptor() : null,
                            out.getFileDescriptor(),
                            err != null ? err.getFileDescriptor() : out.getFileDescriptor(),
                            args, shellCallback, resultReceiver);
                }
            } finally {
                IoUtils.closeQuietly(in);
                IoUtils.closeQuietly(out);
                IoUtils.closeQuietly(err);
                // Write the StrictMode header.
                if (reply != null) {
                    reply.writeNoException();
                } else {
                    StrictMode.clearGatheredViolations();
                }
            }
            return true;
        }
        return false;
    }
----------------------------------------------------------------
    public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
            @Nullable FileDescriptor err,
            @NonNull String[] args, @Nullable ShellCallback callback,
            @NonNull ResultReceiver resultReceiver) throws RemoteException {
        onShellCommand(in, out, err, args, callback, resultReceiver);
    }

调了onShellCommand,这个方法ActivityManagerService有重载:

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    @Override
    public void onShellCommand(FileDescriptor in, FileDescriptor out,
            FileDescriptor err, String[] args, ShellCallback callback,
            ResultReceiver resultReceiver) {
        (new ActivityManagerShellCommand(this, false)).exec(
                this, in, out, err, args, callback, resultReceiver);
    }

onShellCommand中又把具体的事情交给ActivityManagerShellCommand去做了,但是ActivityManagerShellCommand没有重载exec,他的父类ShellCommand的exec又调了父类BasicShellCommandHandler的exec,BasicShellCommandHandler的exec中调了onCommand,而ActivityManagerShellCommand重载了此方法:

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
    @Override
    public int onCommand(String cmd) {
        if (cmd == null) {
            return handleDefaultCommands(cmd);
        }
        final PrintWriter pw = getOutPrintWriter();
        try {
            switch (cmd) {
                case "start":
                case "start-activity":
                    // 这里关注start Activity
                    return runStartActivity(pw);
                case "startservice":
                case "start-service":
                    return runStartService(pw, false);
                case "startforegroundservice":
                case "startfgservice":
                case "start-foreground-service":
                case "start-fg-service":
                    return runStartService(pw, true);
                ......
        return -1;
    }
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
    int runStartActivity(PrintWriter pw) throws RemoteException {
        Intent intent;
        try {
            // 创建intent
            intent = makeIntent(UserHandle.USER_CURRENT);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

            // ..... 配置一些参数
            if (mWaitOption) {
                // 调用startActivityAndWait()方法,启动activity
                result = mInternal.startActivityAndWait(null, SHELL_PACKAGE_NAME, null, intent,
                        mimeType, null, null, 0, mStartFlags, profilerInfo,
                        options != null ? options.toBundle() : null, mUserId);
                res = result.result;
            } else {
                res = mInternal.startActivityAsUserWithFeature(null, SHELL_PACKAGE_NAME, null,
                        intent, mimeType, null, null, 0, mStartFlags, profilerInfo,
                        options != null ? options.toBundle() : null, mUserId);
            }
            ...
    }

mInternal就是AMS,最后解析相应的参数后,通过AMS的startActivityAndWait()方法去启动Activity。

相关文章

网友评论

      本文标题:Android ActivityManagerService--

      本文链接:https://www.haomeiwen.com/subject/ibmvvdtx.html