Service启动流程源码分析(一):startService

来源:互联网 发布:苹果抹除数据后会怎样 编辑:程序博客网 时间:2024/06/09 19:45

Service启动流程源码分析(一):startService

Service是Android组件中最基本也是最为常见用的四大组件之一,分析Service启动流程源码可以加深对Service的了解。Service一共有两种状态,启动和绑定,本文先分析Service启动的流程,大体上和之前的Activity启动流程类似。

Service启动流程源码分析(二):bindService

启动流程

1.多次调用怎么执行 2.执行的线程 3.startService也有注释 分析一下 所有博客都有这几个问题


Activity

本文从Activity的startService(Intent service)入手分析

  • Activity的startService(Intent service)代码如下
@Override    public ComponentName startService(Intent service) {        // mBase在之前Activity启动流程中分析过,是在Activity的attach方法中赋值的,是一个ContextImpl        return mBase.startService(service);    }
  • 调用ContextImpl的startService(service),代码如下
@Override    public ComponentName startService(Intent service) {        warnIfCallingFromSystemProcess();        return startServiceCommon(service, mUser);    }
  • 调用ContextImpl的startServiceCommon(Intent service, UserHandle user),代码如下
private ComponentName startServiceCommon(Intent service, UserHandle user) {        try {            // Android 5.0之后不允许隐式启动Service            validateServiceIntent(service);            // Binder调用ActivityManagerNative.getDefault()启动Service,同Activity的启动            ComponentName cn = ActivityManagerNative.getDefault().startService(                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(                            getContentResolver()), getOpPackageName(), user.getIdentifier());            ...            return cn;        } catch (RemoteException e) {            throw e.rethrowFromSystemServer();        }    }
  • Android 5.0之后不允许隐式启动Service,个人觉得Google是为了安全考虑,限制代码如下
private void validateServiceIntent(Intent service) {        // 5.0以上启动Service时切记要设置相关内容        if (service.getComponent() == null && service.getPackage() == null) {            if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {                IllegalArgumentException ex = new IllegalArgumentException(                        "Service Intent must be explicit: " + service);                throw ex;            } else {                Log.w(TAG, "Implicit intents with startService are not safe: " + service                        + " " + Debug.getCallers(2, 3));            }        }    }

ActivityManagerService

public abstract class ActivityManagerNative extends Binder implements IActivityManager
public interface IActivityManager extends IInterface
从中可以看出ActivityManagerNative是一个Binder类,Service的启动已经通过Binder调用转交到系统服务中了。
IActivityManager Binder具体实现是ActivityManagerService,最终调用到ActivityManagerService的startService
调用进入ActivityManagerService的进程

  • ActivityManagerService的startService(IApplicationThread caller, Intent service,
    String resolvedType, String callingPackage, int userId)是一次Binder调用,代码如下
 @Override    public ComponentName startService(IApplicationThread caller, Intent service,            String resolvedType, String callingPackage, int userId)            throws TransactionTooLargeException {        ...        synchronized(this) {             ...            // mServices是一个ActiveServices            ComponentName res = mServices.startServiceLocked(caller, service,                    resolvedType, callingPid, callingUid, callingPackage, userId);            return res;        }    }

ActiveServices

ActiveServices是AMS中专门抽出来管理Service活动的类,包括启动、绑定等。

  • ActiveServices的startServiceLocked调用了startServiceInnerLocked
  • startServiceInnerLocked调用了bringUpServiceLocked
  • bringUpServiceLocked调用了realStartServiceLocked
  • realStartServiceLocked代码如下
private final void realStartServiceLocked(ServiceRecord r,            ProcessRecord app, boolean execInFg) throws RemoteException {        ...        try {            ...            // 第一步,主要就是通过app.thread(ApplicationThread)Binder调用scheduleCreateService启动Service            app.thread.scheduleCreateService(r, r.serviceInfo,                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),                    app.repProcState);         ...        }         // 第二步,sendServiceArgsLocked调用了ApplicationThread的scheduleServiceArgs方法        sendServiceArgsLocked(r, execInFg, true);        ...    }

ApplicationThread

IApplicationThread thread;
public interface IApplicationThread extends IInterface
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
ApplicationThreadNative的具体实现是ActivityThread中的ApplicationThread
ApplicationThread实现了许多Activity和Service 启动、暂停等有关的操作
调用进入应用程序的进程

  • 第一步,调用ApplicationThread的scheduleCreateService,是一次Binder调用
 public final void scheduleCreateService(IBinder token,                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {            ...            // 类似Activity启动,通过mH发送一条CREATE_SERVICE消息            sendMessage(H.CREATE_SERVICE, s);        }
  • mH收到H.CREATE_SERVICE,调用handleCreateService(CreateServiceData data),代码如下
private void handleCreateService(CreateServiceData data) {        LoadedApk packageInfo = getPackageInfoNoCheck(                data.info.applicationInfo, data.compatInfo);        Service service = null;        try {            // 实例化Service            java.lang.ClassLoader cl = packageInfo.getClassLoader();            service = (Service) cl.loadClass(data.info.name).newInstance();        }         try {            // 创建ContextImpl            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);            // 尝试创建Application            Application app = packageInfo.makeApplication(false, mInstrumentation);            // 将之前创建的ContextImpl给service的mBase赋值            service.attach(context, this, data.info.name, data.token, app,                    ActivityManagerNative.getDefault());            // 调用Service的onCreate方法            service.onCreate();            // 将service对象保存在ActivityThread中            //     final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();            mServices.put(data.token, service);            try {// 调用AMS的serviceDoneExecutingActivityManagerNative.getDefault().serviceDoneExecuting(                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);            }            ...        }     }
  • 第二步,调用ApplicationThread的scheduleServiceArgs,是一次Binder调用
  • scheduleServiceArgs类似scheduleCreateService,通过mH发送H.SERVICE_ARGS,mH收到消息调用handleServiceArgs(ServiceArgsData data),代码如下
private void handleServiceArgs(ServiceArgsData data) {        Service s = mServices.get(data.token);        if (s != null) {            try {                if (!data.taskRemoved) {                    // 调用Service的onStartCommand方法                    res = s.onStartCommand(data.args, data.flags, data.startId);                }...        }        ...    }
  • handleServiceArgs最终调用了Service的onStartCommand方法

总结


流程图待补充

Service启动流程源码分析(二):bindService

原创粉丝点击