# 前言

由于源码分析的代码量比较大,大部分博客网站的内容显示页面都比较窄,显示出来的效果都异常丑陋,所以您也可以直接查看 《 Thinking in Android 》 来阅读这边文章,希望这篇文章能帮你梳理清楚 “Service 的启动流程”


# 核心源码

关键类 路径
ContextImpl.java frameworks/base/core/java/android/app/ContextImpl.java
ContextWrapper.java frameworks/base/core/java/android/content/ContextWrapper.java
ContextThemeWrapper.java frameworks/base/core/java/android/view/ContextThemeWrapper.java
Activity.java frameworks/base/core/java/android/app/Activity.java
ActivityManager.java frameworks/base/core/java/android/app/ActivityManager.java
ActivityManagerService.java frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
ActiveServices.java frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
ActivityThread.java frameworks/base/core/java/android/app/ActivityThread.java

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


# Activity.startService()

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

Intent intent = new Intent(MainActivity.this, xxxService.class);startService(intent);

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

// frameworks/base/core/java/android/app/Activity.javapublic 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.javapublic class ContextThemeWrapper extends ContextWrapper {}// frameworks/base/core/java/android/content/ContextWrapper.javapublic class ContextWrapper extends Context {}

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


# ContextWrapper.startService()

ContextWrapper 中实现了 startService() 方法:

// frameworks/base/core/java/android/content/ContextWrapper.javapublic class ContextWrapper extends Context {    Context mBase;    public ContextWrapper(Context base) {        mBase = base;    }    @Override    public ComponentName startService(Intent service) {        return mBase.startService(service);    }}

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


# ContextImpl.startService()

// frameworks/base/core/java/android/app/ContextImpl.javaclass ContextImpl extends Context {    @Override    public ComponentName startService(Intent service) {        warnIfCallingFromSystemProcess();        return startServiceCommon(service, false, mUser);    }    private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) {        try {            validateServiceIntent(service);            service.prepareToLeaveProcess(this);            // 通过 Binder 进程间通信进入 ActivityManagerService 的 startService() 方法            ComponentName cn = ActivityManager.getService().startService(                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(                    getContentResolver()), requireForeground, getOpPackageName(), user.getIdentifier());            ... ...            return cn;        } catch (RemoteException e) {            throw e.rethrowFromSystemServer();        }    }}

# ActivityManager.getService()

// frameworks/base/core/java/android/app/ActivityManager.javapublic 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()

接下来就执行到 ActivityManagerServicestartService() 方法:

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javapublic class ActivityManagerService extends IActivityManager.Stub        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {    final ActiveServices mServices;    public ComponentName startService(IApplicationThread caller, Intent service,            String resolvedType, boolean requireForeground, String callingPackage, int userId)            throws TransactionTooLargeException {        ... ...        synchronized(this) {            final int callingPid = Binder.getCallingPid();            final int callingUid = Binder.getCallingUid();            final long origId = Binder.clearCallingIdentity();            ComponentName res;            try {                // 调用 ActiveServices 的 startServiceLocked() 方法                res = mServices.startServiceLocked(caller, service, resolvedType, callingPid,                            callingUid, requireForeground, callingPackage, userId);            } finally {                Binder.restoreCallingIdentity(origId);            }            return res;        }    }}

# ActiveServices.startServiceLocked()

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.javapublic 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 相关内容信息。

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


# ActiveServices.startServiceInnerLocked()

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

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.javapublic final class ActiveServices {    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {        ... ...        // 调用 bringUpServiceLocked() 方法        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);        ... ...    }}

# ActiveServices.bringUpServiceLocked()

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

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.javapublic final class ActiveServices {    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,            boolean whileRestarting, boolean permissionsReviewRequired)            throws TransactionTooLargeException {        ... ...        ProcessRecord app;        if (!isolated) {            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);    // 获取 app 对象            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);            if (app != null && app.thread != null) {                try {                    app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);                    // 运行 service 的进程已经启动,调用 realStartServiceLocked() 方法                    realStartServiceLocked(r, app, execInFg);                    return null;                } catch (TransactionTooLargeException e) {                    throw e;                } catch (RemoteException e) {                    Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);                }                // If a dead object exception was thrown -- fall through to                // restart the application.            }        } else {            ... ...        }        // Not running -- get it started, and enqueue this service record        // to be executed when the app comes up.        if (app == null && !permissionsReviewRequired) {            if ((app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,                    hostingRecord, false, isolated, false)) == null) {                String msg = "Unable to launch app "                        + r.appInfo.packageName + "/"                        + r.appInfo.uid + " for service "                        + r.intent.getIntent() + ": process is bad";                Slog.w(TAG, msg);                bringDownServiceLocked(r);                return msg;            }            if (isolated) {                r.isolatedProc = app;            }        }        ... ...        return null;    }}

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">                <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.javapublic 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.javapublic 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);        }    }    }

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


# H.handleMessage()

// frameworks/base/core/java/android/app/ActivityThread.javapublic 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.javapublic 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 相比简单了很多。

更多相关文章

  1. android使用AIDL跨进程通信(IPC)
  2. 聊聊Service(二)
  3. android的TextView的TextWatcher使用
  4. flutter 持久化存储-----数据库sqflite
  5. android在程序中打开另一个程序
  6. Android(安卓)百度地图使几点始终在合适的屏幕范围内显示
  7. android中的4种launchmode详解
  8. ViewGroup中的onInterceptTouchEvent和onTouchEvent调用时序
  9. Android(安卓)6.0 变更

随机推荐

  1. android获取手机电量
  2. android 打开新浪微博代码
  3. Android(安卓)系统是否要重启时弹出框
  4. 在Android(安卓)7.0上PopupWindow.showAs
  5. android MediaPlayer 错误代码(error cod
  6. android 源码编译
  7. Android电子拍卖系统总结四
  8. Ubuntu10.04 64(32)位 android开发环境建
  9. Android【防抖操作的工具类】
  10. android 显示系统时间