Why can play startup animation when there is no Activity? Note that there are several startup animations in Android. We’re not going to talk about Linux startup animations here, we’re going to talk about startup animations in Android rendering, which is when we turn on the phone.

The body of the

Parse init.rc service

service bootanim /system/bin/bootanimation
    class core animation
    user graphics
    group graphics audio
    disabled
    oneshot
    writepid /dev/stune/top-app/tasks
Copy the code

Start the process as soon as you start it, you must look for it in rc. The process responsible for the bootanimation is bootanimation. It was his RC file. Note that the disable flag bit is set.

Let’s take a look at how services are parsed in init. In Android9.0, services, actions, imports, etc. will be parsed into three lists waiting to be executed.

const Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
    constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
    // clang-format off
    static const Map option_parsers = {
        {"capabilities",
                        {1,     kMax, &Service::ParseCapabilities}},
        {"class",       {1,     kMax, &Service::ParseClass}},
        {"console",     {0,     1,    &Service::ParseConsole}},
        {"critical",    {0,     0,    &Service::ParseCritical}},
        {"disabled",    {0,     0,    &Service::ParseDisabled}},
        {"enter_namespace",
                        {2,     2,    &Service::ParseEnterNamespace}},
        {"group",       {1,     NR_SVC_SUPP_GIDS + 1, &Service::ParseGroup}},
        {"interface",   {2,     2,    &Service::ParseInterface}},
        {"ioprio",      {2,     2,    &Service::ParseIoprio}},
        {"priority",    {1,     1,    &Service::ParsePriority}},
        {"keycodes",    {1,     kMax, &Service::ParseKeycodes}},
        {"oneshot",     {0,     0,    &Service::ParseOneshot}},
        {"onrestart",   {1,     kMax, &Service::ParseOnrestart}},
        {"override",    {0,     0,    &Service::ParseOverride}},
        {"oom_score_adjust",
                        {1,     1,    &Service::ParseOomScoreAdjust}},
        {"memcg.swappiness",
                        {1,     1,    &Service::ParseMemcgSwappiness}},
        {"memcg.soft_limit_in_bytes",
                        {1,     1,    &Service::ParseMemcgSoftLimitInBytes}},
        {"memcg.limit_in_bytes",
                        {1,     1,    &Service::ParseMemcgLimitInBytes}},
        {"namespace",   {1,     2,    &Service::ParseNamespace}},
        {"rlimit",      {3,     3,    &Service::ParseProcessRlimit}},
        {"seclabel",    {1,     1,    &Service::ParseSeclabel}},
        {"setenv",      {2,     2,    &Service::ParseSetenv}},
        {"shutdown",    {1,     1,    &Service::ParseShutdown}},
        {"socket",      {3,     6,    &Service::ParseSocket}},
        {"file",        {2,     2,    &Service::ParseFile}},
        {"user",        {1,     1,    &Service::ParseUser}},
        {"writepid",    {1,     kMax, &Service::ParseWritepid}},
    };
    // clang-format on
    return option_parsers;
}
Copy the code

Parse method Pointers for each command are written in this map. Let’s get straight to what Disable does:

Result<Success> Service::ParseDisabled(const std::vector<std::string>& args) {
    flags_ |= SVC_DISABLED;
    flags_ |= SVC_RC_DISABLED;
    return Success();
}
Copy the code

Simply set the DISABLED flag.

When parsing is complete, it tries to execute the parsed service command.

Result<Success> Service::Start() { bool disabled = (flags_ & (SVC_DISABLED | SVC_RESET)); flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START)); if (flags_ & SVC_RUNNING) { if ((flags_ & SVC_ONESHOT) && disabled) { flags_ |= SVC_RESTART; } // It is not an error to try to start a service that is already running. return Success(); } bool needs_console = (flags_ & SVC_CONSOLE); if (needs_console) { if (console_.empty()) { console_ = default_console; } int console_fd = open(console_.c_str(), O_RDWR | O_CLOEXEC); if (console_fd < 0) { flags_ |= SVC_DISABLED; return ErrnoError() << "Couldn't open console '" << console_ << "'"; } close(console_fd); }... pid_t pid = -1; if (namespace_flags_) { pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr); } else { pid = fork(); } if (pid == 0) { ... } if (pid < 0) { pid_ = 0; return ErrnoError() << "Failed to fork"; }... return Success(); }Copy the code

You can see that if the disable and reset flags are not blocked, a new process will be forked through the system. But it’s disabled, so it doesn’t walk down, and instead saves the parsing results. The collection of Services_ vectors held in a ServiceList object.

Author: yjy239 links: www.jianshu.com/p/a79de4a6d… The copyright of the book belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source. Author: yjy239 links: www.jianshu.com/p/a79de4a6d… The copyright of the book belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source. Author: yjy239 links: www.jianshu.com/p/a79de4a6d… The copyright of the book belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.