• service启动流程


    1、以start方式启动

    (1)原应用进程---AMS

    startService

     1 public class ContextWrapper extends Context {
     2       Context mBase;
     3       ......
     4       protected void attachBaseContext(Context base) {
     5           if (mBase != null) {
     6               throw new IllegalStateException("Base context already set");
     7           }
     8           mBase = base;
     9        }
    10        ......
    11        @Override
    12        public ComponentName startService(Intent service) {
    13           return mBase.startService(service);
    14        }
    15        ......
    16 }

    mBase来历

     1 //====ActivityThread.java=====
     2 private Activity performLaunchActivity(...){
     3     ......
     4     ContextImpl appContext = createBaseContextForActivity(r); //代码①
     5     Activity activity = null;
     6     ......
     7     activity.attach(appContext,...);//代码②
     8     ......
     9 }
    10 
    11 //跟进代码①
    12 private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
    13     ......
    14     ContextImpl appContext = ContextImpl.createActivityContext(
    15             this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
    16     ......
    17     return appContext;
    18 }
    19 
    20 //==========ContextImpl.java=======
    21 static ContextImpl createActivityContext(...){
    22      ......
    23      ContextImpl context = new ContextImpl(...);
    24      .....
    25      return context;
    26 }
    27 
    28 //跟进代码②
    29 //======Activity.java extends ContextThemeWrapper extends ContextThemeWrapper extends ContextWrapper extends Context===
    30 final void attach(Context context,...){
    31      attachBaseContext(context);
    32      ......
    33 }
    34 
    35 protected void attachBaseContext(Context newBase) {
    36     super.attachBaseContext(newBase);
    37     ......
    38 }
    39 
    40 //======ContextThemeWrapper.java======
    41 @Override
    42 protected void attachBaseContext(Context newBase) {
    43     super.attachBaseContext(newBase);
    44 }
    45 //========ContextWrapper.java=====
    46 protected void attachBaseContext(Context base) {
    47     if (mBase != null) {
    48         throw new IllegalStateException("Base context already set");
    49     }
    50     mBase = base;
    51 }

    所以mBase就是ContextImpl的实例。

    1 class ContextImpl extends Context {
    2      ......
    3 }

    /

     1 @Override
     2 public ComponentName startService(Intent service) {
     3     warnIfCallingFromSystemProcess();
     4     return startServiceCommon(service, false, mUser);
     5 }
     6 
     7 private ComponentName startServiceCommon(Intent service, boolean requireForeground,
     8         UserHandle user) {
     9     try {
    10         ......
    11         ComponentName cn = ActivityManager.getService().startService(
    12             mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
    13                         getContentResolver()), requireForeground,
    14                         getOpPackageName(), user.getIdentifier());
    15         ......
    16         return cn;
    17     } catch (RemoteException e) {
    18         throw e.rethrowFromSystemServer();
    19     }
    20 }
    在上一篇文章中提到过,ActivityManager.getService()实际上就是获取AMS在当前进程的远程代理Proxy,这里不赘述了。
     1 //=========ActivityManagerService.java============
     2 ......
     3 final ActiveServices mServices;
     4 ......
     5 @Override
     6 public ComponentName startService(IApplicationThread caller, Intent service,
     7         String resolvedType, boolean requireForeground, String callingPackage, int userId)
     8         throws TransactionTooLargeException {
     9     ......
    10     synchronized(this) {
    11         final int callingPid = Binder.getCallingPid(); //调用者进程id
    12         final int callingUid = Binder.getCallingUid();//调用者用户id
    13         final long origId = Binder.clearCallingIdentity();
    14         ComponentName res;
    15         try {
    16             res = mServices.startServiceLocked(caller, service,
    17                     resolvedType, callingPid, callingUid,
    18                     requireForeground, callingPackage, userId);
    19         } finally {
    20             Binder.restoreCallingIdentity(origId);
    21         }
    22         return res;
    23     }
    24 }

    //

     

    (2)AMS到ApplicationThread

    2、以bindService方式启动

  • 相关阅读:
    2016-09-13面试记录
    javascript中的深度拷贝的实现过程及深拷贝的几种方法。
    javascript中的for in循环
    常见的兼容问题及其解决方法。
    一次清空所有数据方法
    数组排序
    css对齐 挖坑~
    css reset样式重置
    CSS 表单
    CSS 表格
  • 原文地址:https://www.cnblogs.com/andy-songwei/p/13509957.html
Copyright © 2020-2023  润新知