编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 1.1App启动流程梳理
  • 1.2ActivityThread分析
  • 1.3Context设计思想
  • 2.1Activity基础介绍
  • 2.2Activity启动流程
  • 2.3Activity布局创建
  • 2.4Activity布局绘制
  • 2.5Service基础介绍
  • 2.6Service启动流程
  • 2.7Receiver广播基础
  • 2.8Receiver深入原理
  • 2.9ContentProvider分析
  • 2.10Fragment实践
  • 2.11Intent深入思考
  • 3.1Paint和Canvas
  • 3.2View的绘制基础
  • 3.3onMeasure流程设计
  • 3.4onLayout流程设计
  • 3.5onDraw流程设计
  • 3.6View工作原理
  • 3.7View刷新设计流程
  • 3.8自定义View控件
  • 3.9自定义ViewGroup控件
  • 4.1Handler基础使用
  • 4.2消息机制流程分析
  • 4.3Handler深度解析
  • 4.4Message深度理解
  • 4.5MessageQueue解析
  • 4.6Looper深度解析
  • 4.7理解Handler同步屏障
  • 4.8ThreadLocal分析
  • 4.9ThreadLocal场景
  • 5.1View事件设计思考
  • 5.2View滑动冲突处理
  • 5.3View事件源码分析
  • 5.4View事件总结案例
  • 6.1DecorView设计思想
  • 6.2视图的载体View
  • 6.3视图管理者Window
  • 6.4窗口管理服务WMS
  • 6.5布局解析者Inflater
  • 7.1AsyncTask深入介绍
  • 7.2HandlerThread设计
  • 7.3IntentService设计
  • 8.1IPC通信方式介绍
  • 8.2AIDL进程间通信
  • 8.7Binder通信机制设计
  • /zh/android/basic/9.1注解设计思想和原理.html
  • 9.2APT技术设计详解
  • 9.3APT多种案例实践

2.6Service启动流程

目录介绍

  • 01.startService源码分析
    • 1.1 ContextImpl类中startService()
    • 1.2 ActivityManagerService中startService()
  • 02.ActivityThread启动
    • 2.1 ActivityThread类中main()方法
    • 2.2 ActivityThread类中scheduleCreateService()
  • 03.bindService源码分析
    • 3.1 绑定一个服务
    • 3.2 ContextImpl类中bindService()

01.startService源码分析

1.1 ContextImpl类中startService()

  • 在 Activity 中使用的 startService 方法是定义在 Context 的抽象类中,它的真正实现类是 ContextImpl,所以先进入 ContextImpl 类。
    • 先从startService开始,然后进入本类的startServiceCommon方法,并最终调用ActivityManagerNative.getDefault()对象的 startService 方法。
    • ActivityManager.getService()获取到IActivityManager对象,并且是通过单利模式创建的。
    @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);
            ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), requireForeground,
                            getOpPackageName(), user.getIdentifier());
            if (cn != null) {
                if (cn.getPackageName().equals("!")) {
                    throw new SecurityException(
                            "Not allowed to start service " + service
                            + " without permission " + cn.getClassName());
                } else if (cn.getPackageName().equals("!!")) {
                    throw new SecurityException(
                            "Unable to start service " + service
                            + ": " + cn.getClassName());
                } else if (cn.getPackageName().equals("?")) {
                    throw new IllegalStateException(
                            "Not allowed to start service " + service + ": " + cn.getClassName());
                }
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
  • 然后看一下validateServiceIntent(service)源码
    • 可以知道如果intent不是new Intent(context,XxService.class),那么就会抛出异常
    private void validateServiceIntent(Intent 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));
            }
        }
    }
  • 然后看看ActivityManager.getService()的代码
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
    
    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;
                }
            };

1.2 ActivityManagerService中startService()

  • 这里调用 mServices 对象的 startServiceLocked 方法,这里的 mServices 对象是 ActiveServices 类
    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
                String resolvedType, int userId) {
        enforceNotIsolatedCaller("startService");
        //......
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }
  • 接着看mServices.startServiceLocked方法,点击去看看源码
    • 下面代码中省略了很多的源代码,源码实在太多呢
    • 通过 retrieveServiceLocked 方法来解析 service 这个 Intent,就是解析前面我们在 AndroidManifest.xml 定义的 Service 标签的 intent-filter 相关内容,然后将解析结果放在 res.record 中,再调用 startServiceInnerLocked 方法。startServiceInnerLocked 方法中会调用 bringUpServiceLocked 方法。
    ComponentName startServiceLocked(IApplicationThread caller, Intent service, 
    	String resolvedType, int callingPid, int callingUid, int userId) {
        ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, 
    		callingPid, callingUid, userId, true, callerFg);
        ServiceRecord r = res.record;
        //这里紧接着会调用 startServiceInnerLocked 方法
        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    }
    
    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
                ServiceRecord r, boolean callerFg, boolean addToStarting) {
            synchronized (r.stats.getBatteryStats()) {
                r.stats.startRunningLocked();
            }
            //这里紧接着会调用 bringUpServiceLocked 方法
            String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
    }
  • 接着看看bringUpServiceLocked()这个方法源码,比较重要
    • 可以看到,当 Service 所在的进程存在时,将调用realStartServiceLocked 方法来启动 Service,否则的话调用 startProcessLocked 方法来启动新进程。
    private final String bringUpServiceLocked(ServiceRecord r,
                int intentFlags, boolean execInFg, boolean whileRestarting) {
        //(1)这里如果当前的 ProcessRecord 不为 null,那就不需要重新创建进程,
    	//而是调用 realStartServiceLocked 方法来启动 Service
        if (app != null && app.thread != null) {
            try {
                app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                realStartServiceLocked(r, app, execInFg);
                return null;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting service " + r.shortName, e);
            }
        }
        //(2)如果是需要创建新进程,那么将调用 ActivityManagerService.startProcessLocked 方法来启动新进程
        if (app == null) {
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {
                //......
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }
        //最后将 ServiceRecord 保存到成员变量 mPendingServices 中
        if (!mPendingServices.contains(r)) {
                mPendingServices.add(r);
        }
    }
  • 最后看看startProcessLocked()这里面的代码,如下所示
    • 通过 Process 的 start 方法启动ActivityThread的新进程,进入该类的 main 方法。
    //在ActivityManagerService类中
    private final void startProcessLocked(ProcessRecord app, String hostingType, 
    	String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    
        boolean isActivityProcess = (entryPoint == null);
        if (entryPoint == null) 
            entryPoint = "android.app.ActivityThread";
        checkTime(startTime, "startProcess: asking zygote to start proc");
        //通过 processName,uid 等启动新进程
        Process.start(entryPoint, 
    			app.processName, uid, uid, gids, debugFlags, mountExternal, 
    			app.info.targetSdkVersion, app.info.seinfo, requiredAbi, 
    			instructionSet, app.info.dataDir, entryPointArgs);
    }
    
    //在Process类中
    public static final ProcessStartResult start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int debugFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String invokeWith,
                                  String[] zygoteArgs) {
        return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    }

02.ActivityThread启动

2.1 ActivityThread类中main()方法

  • main()方法源码如下所示
    • 1.绑定应用进程到ActivityManagerService
      • 在 Android 应用程序中,每一个进程对应一个 ActivityThread 实例,然后这里创建了 ActivityThread 对象并调用了其 attach 方法
    • 2.主线程Handler消息处理
      • 启动looper轮询器,所以在activity或者service创建handler对象时,不需要手动调用looper。原因就是在这里
      • 首先Looper.prepareMainLooper();是为主线程创建了Looper,然后thread.getHandler();是保存了主线程的Handler,最后Looper.loop();进入消息循环。
    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        CloseGuard.setEnabled(false);
        // 初始化应用中需要使用的系统路径
        Environment.initForCurrentUser();
    
        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());
    
        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
        //设置进程的名称
        Process.setArgV0("<pre-initialized>");
    
        Looper.prepareMainLooper();
        //创建ActivityThread 对象
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
    
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
    
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
    
        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();
    
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
  • 接着看看thread.attach(false)方法代码
    • main()方法通过thread.attach(false)绑定应用进程。ActivityManagerNative通过getDefault()方法返回ActivityManagerService实例,ActivityManagerService通过attachApplication将ApplicationThread对象绑定到ActivityManagerService,而ApplicationThread作为Binder实现ActivityManagerService对应用进程的通信和控制。
    • 在ActivityManagerService内部,attachApplication实际是通过调用attachApplicationLocked实现的,这里采用了synchronized关键字保证同步。
    private void attach(boolean system) {
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            //这里调用了 ActivityManagerProxy.attachApplication 方法。
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            // Ignore
        }
    }
    
    //然后看看attachApplication方法
    @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
  • 接着看看attachApplicationLocked(thread, callingPid)方法代码
    • 如果是启动 Service 将调用 ActiveServices 对象的 attachApplicationLocked 方法,而如果是启动 Activity 将调用 ActivityStackSupervisor 对象的 attachApplicationLocked 方法。
    • attachApplicationLocked的实现较为复杂,其主要功能分为两部分:
      • thread.bindApplication
      • mStackSupervisor.attachApplicationLocked(app)
    private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {
        if (app.instr != null) {
            thread.bindApplication(processName, appInfo, providers,
                    app.instr.mClass,
                    profilerInfo, app.instr.mArguments,
                    app.instr.mWatcher,
                    app.instr.mUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(getGlobalConfiguration()), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial);
        } else {
            thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                    null, null, null, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(getGlobalConfiguration()), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial);
        }
        
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
    
        // Find any services that should be running in this process...
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }
        
    }
  • 接着看看thread.bindApplication方法源代码,在ActivityThread类中
    • 该bindApplication方法的实质是通过向ActivityThread的消息队列发送BIND_APPLICATION消息
    • 消息的处理调用handleBindApplication方法,handleBindApplication方法比较重要的是会调用如下方法mInstrumentation.callApplicationOnCreate(app),callApplicationOnCreate即调用应用程序Application的onCreate()方法,说明Application的onCreate()方法会比所有activity的onCreate()方法先调用。
    public final void bindApplication(String processName, ApplicationInfo appInfo,
            List<ProviderInfo> providers, ComponentName instrumentationName,
            ProfilerInfo profilerInfo, Bundle instrumentationArgs,
            IInstrumentationWatcher instrumentationWatcher,
            IUiAutomationConnection instrumentationUiConnection, int debugMode,
            boolean enableBinderTracking, boolean trackAllocation,
            boolean isRestrictedBackupMode, boolean persistent, Configuration config,
            CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
            String buildSerial) {
        if (services != null) {
            // Setup the service cache in the ServiceManager
            ServiceManager.initServiceCache(services);
        }
        setCoreSettings(coreSettings);
    
        AppBindData data = new AppBindData();
        //省略部分代码
        sendMessage(H.BIND_APPLICATION, data);
    }
    
    
    //通过BIND_APPLICATION这个常量,找到接收消息的方法
    //在ActivityThread类,找到handleBindApplication方法
    try {
        mInstrumentation.callApplicationOnCreate(app);
    } catch (Exception e) {
        if (!mInstrumentation.onException(app, e)) {
            throw new RuntimeException(
              "Unable to create application " + app.getClass().getName()
              + ": " + e.toString(), e);
        }
    }
  • 接着看看mStackSupervisor.attachApplicationLocked(app)这里面做了什么
    • mStackSupervisor为ActivityManagerService的成员变量,类型为ActivityStackSupervisor。
    • 从注释可以看出,mStackSupervisor为Activity堆栈管理辅助类实例。ActivityStackSupervisor的attachApplicationLocked()方法的调用了realStartActivityLocked()方法,在realStartActivityLocked()方法中,会调用scheduleLaunchActivity()方法:
    • 这里面代码比较复杂,只是摘取部分代码
    final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
     
        //...  
        try {
            //...
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    new Configuration(mService.mConfiguration),
                    r.compat, r.icicle, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profileFile, profileFd,
                    profileAutoStop);
     
            //...
     
        } catch (RemoteException e) {
            //...
        }
        //...    
        return true;
    }

2.2 ActivityThread类中scheduleCreateService()

  • 然后看看ActivityThread.scheduleCreateService()
    • 调用子类的 scheduleCreateService 方法,即最终调用 ApplicationThreadNative 的子类 ApplicationThread 的 scheduleCreateService 方法。
    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);
    }
  • 通过 Handler 发送 Message 来处理该操作,并进入到 H 的 handleMessage 方法中,其识别码为 CREATE_SERVICE。
    • H.handleMessage()
    private class H extends Handler {
        public void handleMessage(Message msg) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
            //这里调用 handleCreateService 方法
            handleCreateService((CreateServiceData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }
  • 然后接着往下看ApplicationThread.handleCreateService()
    • 处通过类加载器 ClassLoader 来加载 Service 对象
    • 这里先创建一个 ContextImpl 对象,每个 Activity 和 Service 都有一个 Context 对象。
    private void handleCreateService(CreateServiceData data) {
        Service service = null;
        try {
            //(1)通过类加载器来加载 Service 对象
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            //......
        }
        //(2)这里创建 ContextImpl 对象
        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,ActivityManagerNative.getDefault());
        //(3)这里调用 Service 的 onCreate 方法
        service.onCreate();
        mServices.put(data.token, service);
    }

03.bindService源码分析

3.1 绑定一个服务

  • 代码如下所示
    private void test(){
        Intent intent = new Intent(this, XXXService.class);
        // bindService 的具体实现在 ContextImpl
        // BIND_AUTO_CREATE 参数具体使用的代码 ActivityServices
        bindService(intent, conn, BIND_AUTO_CREATE);
    }
    
    private ServiceConnection conn = new ServiceConnection() {  
    
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
           // 绑定成功
           ...
        }  
    
        @Override  
        public void onServiceDisconnected(ComponentName name) { 
          // 绑定结束 
           ...  
        }
    }

3.2 ContextImpl类中bindService()

  • 代码如下所示
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        // mMainThread.getHandler(),传入的 handle 是主线程的 Handle
        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
                Process.myUserHandle());
    }
    
    private boolean bindServiceCommon(Intent service, ServiceConnection conn, 
    	int flags, Handler handler, UserHandle user) {
    
        IServiceConnection sd;
        //...
        if (mPackageInfo != null) {
            // 1,将传入的 ServiceConnection 转化为 IServiceConnection 返回
            // mPackgeInfo 是 LoadedApk
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
        }
        validateServiceIntent(service);
        try {
            IBinder token = getActivityToken();
            ...
            // 2,Binder 调用 AMS 的 bindService 方法,下面具体分析
            int res = ActivityManagerNative.getDefault().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
            return res != 0;
        } 
        //...
    }
  • 接着看看getServiceDispatcher这个方法
    public final IServiceConnection getServiceDispatcher(ServiceConnection c, 
    	Context context, Handler handler, int flags) {
    
        synchronized (mServices) {
            LoadedApk.ServiceDispatcher sd = null;
            // private final ArrayMap<Context,
            // ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
            // 根据当前的 Context 获取 ArrayMap<ServiceConnection,  LoadedApk.ServiceDispatcher>
            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
            if (map != null) {
                // 如果存在,尝试根据当前的 ServiceConnection 获取 ServiceDispatcher
                sd = map.get(c);
            }
            if (sd == null) {
                // 如果与 ServiceConnection 对应的 ServiceDispatcher 不存在,创建一个保存了当前 
    			// ServiceConnection 的 ServiceDispatcher 对象,
                // 并将之前传入的主线的 Handle 保存,同时创建一个 InnerConnection 对象保存
                sd = new ServiceDispatcher(c, context, handler, flags);
                if (map == null) {
                    map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
                    mServices.put(context, map);
                }
                // 将该 ServiceConnection 与 ServiceDispatcher 关系保存
                map.put(c, sd);
            } else {
                // 如果最开始就获取到 ServiceDispatcher,比如多次 bindService,
                // 就会调用 ServiceDispatcher 的 validate 判断此次 bindService 是否合法
                // validate 的判断逻辑比较简单:
    			// 1.判断当前的 context 是否和之前 bindService 的一样 
    			// 2.判断当前 handler 是否是主线程的 handle
                // 以上两个条件都满足的情况下正常执行,反之抛出相应的异常
                sd.validate(context, handler);
            }
            return sd.getIServiceConnection();
        }
    }
  • 接着找到ActivityManagerService.bindService()类
    • 可以看到调用 ActiveServices 的 bindServiceLocked 方法,返回是int。注意这里用到了synchronized关键字,避免多次绑定
    public int bindService(IApplicationThread caller, IBinder token, Intent service, 
    	String resolvedType, IServiceConnection connection, 
    	int flags, String callingPackage, int userId) throws TransactionTooLargeException {
    
        //...
        synchronized(this) {
            // 调用 ActiveServices 的 bindServiceLocked 方法
            return mServices.bindServiceLocked(caller, token, service,
                    resolvedType, connection, flags, callingPackage, userId);
        }
    }
  • 接着又来看看mServices.bindServiceLocked里面的代码
    • 大概流程是:ActiveServices.bindServiceLocked() -> bringUpServiceLocked() -> realStartServiceLocked()
    private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, 
    	boolean execInFg) throws RemoteException {
        //...
        try {
            //...
            // 第一步,调用 ApplicationThread 的 scheduleCreateService 方法,
    		// 之后会实例化 Service 并调用 Service 的 onCreate 方法,这里的过程跟上面 startService 中一样。
            // 不会调用 onStartCommand
            app.thread.scheduleCreateService(r, r.serviceInfo, 
    				mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
    
        } 
        //...
        // 第二步,调用 requestServiceBindingLocked
        requestServiceBindingLocked(r, execInFg);
        updateServiceClientActivitiesLocked(app, null, true);
    
        // 第三步
        // If the service is in the started state, and there are no
        // pending arguments, then fake up one so its onStartCommand() will
        // be called.
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, 
    			r.makeNextStartId(), null, null));
        }
        // StartItem 的 taskRemoved 如果是 false 的话,
    	// 调用下面方法会调用 Service 的 onStartCommand
        sendServiceArgsLocked(r, execInFg, true);
        //...
    }
    
    private final boolean requestServiceBindingLocked(ServiceRecord r, 
    	IntentBindRecord i, boolean execInFg, boolean rebind) 
    	throws TransactionTooLargeException {
    
        //...
        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                //...
                // 调用 ApplicationThread 的 scheduleBindService 方法
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
            } 
            //...
        }
        //...
        return true;
    }
  • 最后看看这个方法ApplicationThread.scheduleBindService()
    • 调用 ApplicationThread 的 scheduleBindService,scheduleBindService 通过 mH 发送一个 H.BIND_SERVICE 消息,mH 收到该消息调用 handleBindService(BindServiceData data)。
    private void handleBindService(BindServiceData data) {
       // 根据 token 获取 Service token 具体分析
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                // rebind 具体分析
                if (!data.rebind) {
                    // 调用 Service 的 onBind,返回给客户端调用的 Binder
                    IBinder binder = s.onBind(data.intent);
                    // 调用 AMS 的 publishService,进而通知客户端连接成功
                    ActivityManagerNative.getDefault()
                        .publishService(data.token, data.intent, binder);
                } else {
                    s.onRebind(data.intent);
                    ActivityManagerNative.getDefault()
                        .serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON,
                         0, 0);
                }
                ensureJitEnabled();
            }
            ...
        }
    }
贡献者: yangchong211
上一篇
2.5Service基础介绍
下一篇
2.7Receiver广播基础