「 Android 10 四大组件 」系列—Service 的 “ 启动流程 “

作者:DeepCoder

核心源码

关键类路径

Service 的启动过程相对 Activity 的启动过程来说简单了很多,我们都知道怎么去创建和启动一个 Service, 那么你有没有从源码角度研究过 Service 启动后在系统层是如何运作的 ?

Activity.startService()

首先我们知道:要启动一个 Service 的时候,一般都是在 Activity 中通过 startService() 来启动:

// frameworks/base/core/java/android/app/ActivityManager.java

public class ActivityManager {

    @UnsupportedAppUsage
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    @UnsupportedAppUsage
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

}

但是我们在 Activity 源码中并没有实现 startService() 方法,那它在哪里被调用的?找不到我们就去 Activity 的父类中找。

// frameworks/base/core/java/android/app/Activity.java

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback, WindowControllerCallback,
        AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {

}

// frameworks/base/core/java/android/view/ContextThemeWrapper.java

public class ContextThemeWrapper extends ContextWrapper {

}

// frameworks/base/core/java/android/content/ContextWrapper.java
public class ContextWrapper extends Context {

}

Activity 继承了 ContextThemeWrapper 类, ContextThemeWrapper 又继承了 ContextWrapper类, ContextWrapper 又继承了 Context 类。

ContextWrapper.startService()

在 ContextWrapper 中实现了 startService() 方法:

// frameworks/base/core/java/android/app/ActivityManager.java

public class ActivityManager {

    @UnsupportedAppUsage
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    @UnsupportedAppUsage
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

}

所以 startService() 方法其实是由 ContextWrapper 实现的,紧接着又调用了 mBase.startService() 方法, mBase 对象是 Context 的子类 ContextImpl ,所以调用最终进入 ContextImpl类的 startService() 方法。

ContextImpl.startService()

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

public final class ActiveServices {

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
            throws TransactionTooLargeException {
        return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
                callingPackage, userId, false);
    }

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage,
            final int userId, boolean allowBackgroundActivityStarts)
            throws TransactionTooLargeException {
        ... ...

        // 解析 AndroidManifest.xml 文件中配置 Service 的 intent-filter 相关内容信息
        ServiceLookupResult res = retrieveServiceLocked(service, null, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false, false);
        if (res == null) {
            return null;
        }
        ... ...

        ServiceRecord r = res.record;
        ... ...

        // 调用 startServiceInnerLocked() 方法
        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
        return cmp;
    }

}

ActivityManager.getService()

// frameworks/base/core/java/android/app/ActivityManager.java

public class ActivityManager {

    @UnsupportedAppUsage
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    @UnsupportedAppUsage
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

}

ActivityManagerService.startService()

接下来就执行到 ActivityManagerService 的 startService() 方法:

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

public final class ActiveServices {

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        ... ...

        try {
            ... ...

            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo), app.getReportedProcState());
            ... ...

        }
        ... ...

    }

}

ActiveServices.startServiceLocked()

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

public final class ActiveServices {

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
            throws TransactionTooLargeException {
        return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
                callingPackage, userId, false);
    }

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage,
            final int userId, boolean allowBackgroundActivityStarts)
            throws TransactionTooLargeException {
        ... ...

        // 解析 AndroidManifest.xml 文件中配置 Service 的 intent-filter 相关内容信息
        ServiceLookupResult res = retrieveServiceLocked(service, null, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false, false);
        if (res == null) {
            return null;
        }
        ... ...

        ServiceRecord r = res.record;
        ... ...

        // 调用 startServiceInnerLocked() 方法
        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
        return cmp;
    }

}

通过 retrieveServiceLocked() 方法来解析 AndroidManifest.xml 文件中配置 Service 的 intent-filter 相关内容信息。

当解析完 Service 的 intent-filter 相关内容信息后,解析的结果会保存在 res.record 变量中。而 res 变量是一个 ServiceLookupResult 类型的对象,它的 record 变量则是一个 ServiceRecord 类型对象,用来表示一个 Service 。

ActiveServices.startServiceInnerLocked()

ActiveServices 的 startServiceLocked() 方法最后调用了 startServiceInnerLocked() 方法:

//

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.documentsui">

    <application
        android:name=".DocumentsApplication"
        android:label="@string/app_label"
        android:icon="@drawable/app_icon"
        android:supportsRtl="true"
        android:allowBackup="true"
        android:backupAgent=".prefs.BackupAgent"
        android:fullBackupOnly="false">

        <!-- Run FileOperationService in a separate process so that we can use FileLock class to
            wait until jumbo clip is done writing to disk before reading it. See ClipStorage for
            details. -->
        <service
            android:name=".services.FileOperationService"
            android:exported="false"
            android:process=":com.android.documentsui.services">
        </service>

    </application>
</manifest>

ActiveServices.bringUpServiceLocked()

调用 bringUpServiceLocked() 方法进一步处理:

// frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread extends ClientTransactionHandler {

    class H extends Handler {

        public void handleMessage(Message msg) {
            switch (msg.what) {

                case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                    handleCreateService((CreateServiceData)msg.obj);    // 调用 handleCreateService() 方法
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

            }
        }

    }
}

bringUpServiceLocked() 方法首先通过 getProcessRecordLocked() 方法去获取 app 对象,它是一个 ProcessRecord 类型的对象,如果它不为空,说明 Service 要运行的进程已经存在。

Service 运行的进程有两种:

(1)一种是默认的,即运行在 Activity 启动 Service 的那个进程里,也就是说在哪个进程里调用了 startService() 方法,启动的 service 就运行在哪个进程里。

(2)一种是给 Service 一个单独的进程运行,比如在 AndroidManifest 文件里配置了如下内容:

//

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.documentsui">

    <application
        android:name=".DocumentsApplication"
        android:label="@string/app_label"
        android:icon="@drawable/app_icon"
        android:supportsRtl="true"
        android:allowBackup="true"
        android:backupAgent=".prefs.BackupAgent"
        android:fullBackupOnly="false">

        <!-- Run FileOperationService in a separate process so that we can use FileLock class to
            wait until jumbo clip is done writing to disk before reading it. See ClipStorage for
            details. -->
        <service
            android:name=".services.FileOperationService"
            android:exported="false"
            android:process=":com.android.documentsui.services">
        </service>

    </application>
</manifest>

在这段配置里有 android:process=“xxx” 声明,这个声明用来实现 service 单独运行在 “xxx” 进程里。这样做的好处是, 即使应用程序无法工作,由于 service 单独运行在一个进程里,所以会继续工作 。

回到前面的方法,如果变量 app 为空,就代表 service 要运行的进程还没有启动,于是调用 startProcessLocked() 方法去启动一个新的进程。

如果 app 不为空,采用默认的方式启动 Service,最终调用到 realStartServiceLocked() 方法:

ActiveServices.realStartServiceLocked()

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

public final class ActiveServices {

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        ... ...

        try {
            ... ...

            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo), app.getReportedProcState());
            ... ...

        }
        ... ...

    }

}

在这个方法中,app 对象的 thread 变量是一个 ApplicationThread Binder 对象,调用它的scheduleCreateService() 方法之后,会进入客户端的 ActivityThread 中。

ActivityThread.scheduleCreateService()

// frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread extends ClientTransactionHandler {

    // ApplicationThread 是一个 Binder
    private class ApplicationThread extends IApplicationThread.Stub {

        public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;

            sendMessage(H.CREATE_SERVICE, s);
        }

    }

}

ApplicationThread 的 scheduleCreateService() 方法通过调用 sendMessage() 方法来发送一个 msg 消息 ,当 Handler 接收到了 msg 消息之后,它会调用 handleCreateService() 方法来做进一步处理。

H.handleMessage()

// frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread extends ClientTransactionHandler {

    class H extends Handler {

        public void handleMessage(Message msg) {
            switch (msg.what) {

                case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                    handleCreateService((CreateServiceData)msg.obj);    // 调用 handleCreateService() 方法
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

            }
        }

    }
}

ActivityThread.handleCreateService()

// frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread extends ClientTransactionHandler {

    private void handleCreateService(CreateServiceData data) {
        ... ...

        LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService());
            service.onCreate();    // 进入 Service.onCreate() 方法
            mServices.put(data.token, service);
            try {
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }

}

在 ActivityThread 类的 handleCreateService() 方法中,首先通过 ClassLoader 类把 Service 加载进来,而参数 data.info.name 表示这个 Service 的名字, instantiateService() 方法是创建一个 Service 实例。接着, 创建一个 Context 对象 ,作为上下文环境之用。

handleCreateService() 方法最后调用了 service 的 onCreate() 方法 ,当这个方法被调用之后, 就会进入应用程序里 Service 的 onCreate() 方法 。

至此,Service 的启动就分析完毕,这个过程与启动 Activity 相比简单了很多。

总结

看到最后,希望这篇文章能帮你梳理清楚 “Service 的启动流程” 。

我整理了一些Activity的资料,如果你有需要可以私信我获取

还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅的精品资料

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

如果你有需要的话,可以点赞+评论关注我,然后私信我【学习】我发给你

点击【Android学习PDF+架构视频+面试文档+源码笔记】加入我们的圈子领取资料和我们一起吧学习交流吧!

猜你喜欢

转载自blog.csdn.net/ajsliu1233/article/details/107372086