前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android StartService()源码分析(一)

Android StartService()源码分析(一)

原创
作者头像
木子杂志
修改2020-08-05 18:08:48
8320
修改2020-08-05 18:08:48
举报
文章被收录于专栏:木子杂志木子杂志
基于 android9.0

场景:在 APP M 中启动 APP N 中一个服务,即目标服务和 APP M 不在同一个进程

​启动流程简述
  • activity启动一个服务,调用 AMS.startService()方法,告诉 AMS 我要启动一个新的 服务S
  • activity 进程 标记 A , AMS 进程标记 B
  • AMS从ProcessRecord中发现当前服务S所在的进程不存在,创建进程标记C,
  • 通过反射创建服务 S 对象,先进程 C 的 Application的生命周期被回调,然后服务 S 的onCreate()和onStartCommand()方法被回调
入口 startService()

在 activity 中启动服务

代码语言:javascript
复制
public class StartActivity extends AppCompatActivity {
       @Override
       protected void onCreate(@Nullable Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           //【1.1】
           startService(new Intent(""));
      }
}

当前 activity 的进程标记为 A

【1.1】ContextWrapper.startService()

【ContextWrapper.java】【/frameworks/base/core/java/android/content/ContextWrapper.java】

代码语言:javascript
复制
public class ContextWrapper extends Context {

   @Override
   public ComponentName startService(Intent service) {
       //实现类是 ContextImpl 【1.2】
       return mBase.startService(service);
  }        
}
【1.2】ContextImpl

startService()

【--->】

startServiceCommon()

代码语言:javascript
复制
class ContextImpl extends Context {
   
  @Override
   public ComponentName startService(Intent service) {
       warnIfCallingFromSystemProcess();
       // 调用 startServiceCommon()
       return startServiceCommon(service, mUser);
  }
   //
   private ComponentName startServiceCommon(Intent service, boolean requireForeground,
           UserHandle user) {
       try {
           //关键代码
           //参数:
           //mMainThread.getApplicationThread(): 进程 APP 进程A的 ApplicationThread 跟 AMS 交互
           //service : Intent信息
           // 进入 AMS【2.0】
           ComponentName cn = ActivityManager.getService().startService(
               mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                           getContentResolver()), requireForeground,
                           getOpPackageName(), user.getIdentifier());
           //...
           return cn;
      } catch (RemoteException e) {
      }
  }    
}
【2.0】AMS

当前 AMS 的进程标记为 B

代码语言:javascript
复制
public class ActivityManagerService extends IActivityManager.Stub
       implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

   @Override
   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 {
               //关键代码 【2.1】
               res = mServices.startServiceLocked(caller, service,
                       resolvedType, callingPid, callingUid,
                       requireForeground, callingPackage, userId);
          } finally {
               Binder.restoreCallingIdentity(origId);
          }
           return res;
      }
  }        
   
      }
【2.1】ActiveServices

startServiceLocked()

【--->】

startServiceInnerLocked()

【--->】

bringUpServiceLocked()

代码语言:javascript
复制
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 {
       //...
       

       ServiceLookupResult res =
           retrieveServiceLocked(service, resolvedType, callingPackage,
                   callingPid, callingUid, userId, true, callerFg, false, false);
   
       //1.
       //从ServiceLookupResult中获取ServiceRecord对象
       ServiceRecord r = res.record;


       //2.
       final ServiceMap smap = getServiceMapLocked(r.userId);
       //3.
       boolean addToStarting = false;
       //...

       //传入 1,2,3 中的参数 调用startServiceInnerLocked()
       ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
       return cmp;
  }

   //
   ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
           boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
       
       //关键代码
       String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
       if (error != null) {
           return new ComponentName("!!", error);
      }
       //...
       return r.name;
  }        

   //
   private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
           boolean whileRestarting, boolean permissionsReviewRequired)
           throws TransactionTooLargeException {

       //...
       final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
       final String procName = r.processName;
       String hostingType = "service";
       ProcessRecord app;

       if (!isolated) {
            //根据进程名和uid,查询ProcessRecord
           app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
      }
       // Not running -- get it started, and enqueue this service record
       // to be executed when the app comes up.
       //启动service所要运行的进程
       if (app == null && !permissionsReviewRequired) {
           //mAm是ActivityManagerService,通过 AMS 创建service 所在进程标记为 C
           if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                   hostingType, r.name, false, isolated, false)) == null) {
               bringDownServiceLocked(r);
               return msg;
          }
           if (isolated) {
               r.isolatedProc = app;
          }
      }
       //...
       return null;
  }
  }
【2.1】ActivityManagerService.startProcessLocked()

startProcessLocked()

【--->】

startProcessLocked()

【--->】

startProcess()

【--->】

Process.start()

代码语言:javascript
复制
public class ActivityManagerService extends IActivityManager.Stub
       implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
   
   @GuardedBy("this")
   final ProcessRecord startProcessLocked(String processName,
           ApplicationInfo info, boolean knownToBeDead, int intentFlags,
           String hostingType, ComponentName hostingName, boolean allowWhileBooting,
           boolean isolated, boolean keepIfLarge) {
           //
       return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
               hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
               null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
               null /* crashHandler */);
  }
   //...
  @GuardedBy("this")
   private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
           ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
           String seInfo, String requiredAbi, String instructionSet, String invokeWith,
           long startTime) {
       if (mConstants.FLAG_PROCESS_START_ASYNC) {
           mProcStartHandler.post(() -> {
               try {
                   //...
                   //
                   final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
                           app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
                           requiredAbi, instructionSet, invokeWith, app.startTime);
                   synchronized (ActivityManagerService.this) {
                       handleProcessStartedLocked(app, startResult, startSeq);
                  }
              } catch (RuntimeException e) {
                 
              }
          });
           return true;
      } else {
           //...
      }
  }
   //
   private ProcessStartResult startProcess(String hostingType, String entryPoint,
           ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
           String seInfo, String requiredAbi, String instructionSet, String invokeWith,
           long startTime) {
       try {
           final ProcessStartResult startResult;
           if (hostingType.equals("webview_service")) {
               startResult = startWebView(entryPoint,
                       app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                       app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                       app.info.dataDir, null,
                       new String[] {PROC_START_SEQ_IDENT + app.startSeq});
          } else {
               // 关键代码 【2.2】ActivityThread
               startResult = Process.start(entryPoint,
                       app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                       app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                       app.info.dataDir, invokeWith,
                       new String[] {PROC_START_SEQ_IDENT + app.startSeq});
          }
           checkTime(startTime, "startProcess: returned from zygote!");
           return startResult;
      } finally {
           Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
      }
  }    
   
    }

ActivityManagerService调用Process.start方法,

通过Socket通信方式向Zygote发送创建进程C的请求.

Zygote通过fork的方法,将zygote进程复制生成进程C,并将ActivityThread相关的资源加载到新进程,ActivityThread是进程 C的主线程

【2.2】 ActivityThread

main()

【--->】

attach()

【--->】

调用到AMS.attachApplication()

代码语言:javascript
复制
public final class ActivityThread extends ClientTransactionHandler {
   
  public static void main(String[] args) {

       Looper.prepareMainLooper();
       //...
       ActivityThread thread = new ActivityThread();
       //关键代码
       thread.attach(false, startSeq);

       if (sMainThreadHandler == null) {
           sMainThreadHandler = thread.getHandler();
      }
       Looper.loop();
  }  
   //
   private void attach(boolean system, long startSeq) {
       sCurrentActivityThread = this;
       mSystemThread = system;
       if (!system) {
           //
           final IActivityManager mgr = ActivityManager.getService();
           try {
               //关键代码
               //AMS绑定ApplicationThread对象 ##### 【2.3】
               mgr.attachApplication(mAppThread, startSeq);
          } catch (RemoteException ex) {
          }
         //...  
      }
  }    
}
【2.3】 AMS

当前所在进程为 B

attachApplication()

【--->】

attachApplicationLocked()

代码语言:javascript
复制
public class ActivityManagerService extends IActivityManager.Stub
       implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
   
   @Override
   public final void attachApplication(IApplicationThread thread, long startSeq) {
       synchronized (this) {
           //
           attachApplicationLocked(thread, callingPid, callingUid, startSeq);
      }
  }
   //
   @GuardedBy("this")
   private final boolean attachApplicationLocked(IApplicationThread thread,
           int pid, int callingUid, long startSeq) {

       ProcessRecord app;
       if (pid != MY_PID && pid >= 0) {
           synchronized (mPidsSelfLocked) {
               app = mPidsSelfLocked.get(pid);
          }
      } else {
           app = null;
      }

       boolean badApp = false;
       
       //...
       // Find any services that should be running in this process...
       if (!badApp) {
           try {
               //关键代码: service 相关 寻找所有需要在该进程中运行的服务
               //【2.4】
               didSomething |= mServices.attachApplicationLocked(app, processName);
          } catch (Exception e) {
          }
      }


       return true;
  }    
      }
【2.4】 ActiveServices

当前在进程 B

代码语言:javascript
复制
public final class ActiveServices {
    
    boolean attachApplicationLocked(ProcessRecord proc, String processName)
            throws RemoteException {
        boolean didSomething = false;
        // Collect any services that are waiting for this process to come up.
        //遍历列表,列表项为:等待在该进程启动的服务
        if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
            try {
                for (int i=0; i<mPendingServices.size(); i++) {
                    sr = mPendingServices.get(i);
                    if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                            || !processName.equals(sr.processName))) {
                        continue;
                    }

                    mPendingServices.remove(i);
                    i--;
                    proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode,
                            mAm.mProcessStats);
                    //关键代码 启动服务,即将进入服务的生命周期
                    realStartServiceLocked(sr, proc, sr.createdFromFg);
                    didSomething = true;
                    if (!isServiceNeededLocked(sr, false, false)) {
                        // We were waiting for this service to start, but it is actually no
                        // longer needed.  This could happen because bringDownServiceIfNeeded
                        // won't bring down a service that is pending...  so now the pending
                        // is done, so let's drop it.
                        bringDownServiceLocked(sr);
                    }
                }
            } catch (RemoteException e) {
            }
        }
        return didSomething;
    }
    
    
    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        r.app = app;

        boolean created = false;
        try {
            // 关键代码 当前在进程 B,通过 binder 通信 调用进程 C 的ApplicationThread的scheduleCreateService()
            //【2.5】
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
            throw e;
        }
        if (r.whitelistManager) {
            app.whitelistManager = true;
        }

        requestServiceBindingsLocked(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, 0));
        }

        //
        sendServiceArgsLocked(r, execInFg, true);
    }
    
    //
    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {
        final int N = r.pendingStarts.size();
        ArrayList<ServiceStartArgs> args = new ArrayList<>();

        ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
        slice.setInlineCountLimit(4);
        try {
            //关键代码
            //【2.6】
            r.app.thread.scheduleServiceArgs(r, slice);
        } catch (TransactionTooLargeException e) {
        }
    }
    
}
【2.5】ApplicationThread.scheduleCreateService()

ApplicationThread.scheduleCreateService()

【--->】

handler.sendMessage(H.UNBIND_SERVICE, s)

【--->】

ActivityThread.handleCreateService()

至此进程 C 的 Application 创建成功,目标服务创建成功且回调了其onCreate()方法

代码语言:javascript
复制
public final class ActivityThread extends ClientTransactionHandler {
    
    
    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;
            // 使用 handler 发送消息
            sendMessage(H.CREATE_SERVICE, s);
        }
        //...
}

    //
    private void handleCreateService(CreateServiceData data) {

        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            //通过反射创建进程 C 的目标服务对象 在AppComponentFactory中完成
            service = packageInfo.getAppFactory()
                    .instantiateService(cl, data.info.name, data.intent);
        } catch (Exception e) {
        }

        try {

            //创建ContextImpl对象
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            //创建Application对象
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            //调用服务onCreate()方法
            service.onCreate();
            mServices.put(data.token, service);
            try {
                //告诉 AMS 服务创建完成
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
        }
    }
}
【2.6】ApplicationThread.scheduleServiceArgs()

ApplicationThread.scheduleServiceArgs()

【--->】

handler.sendMessage(H.SERVICE_ARGS, s)

【--->】

ActivityThread.handleServiceArgs()

代码语言:javascript
复制
public final class ActivityThread extends ClientTransactionHandler {
    
    
    private class ApplicationThread extends IApplicationThread.Stub {
        //...
        
        public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
            List<ServiceStartArgs> list = args.getList();

            for (int i = 0; i < list.size(); i++) {
                ServiceStartArgs ssa = list.get(i);
                ServiceArgsData s = new ServiceArgsData();
                s.token = token;
                s.taskRemoved = ssa.taskRemoved;
                s.startId = ssa.startId;
                s.flags = ssa.flags;
                s.args = ssa.args;
                // 使用 handler 发送消息
                sendMessage(H.SERVICE_ARGS, s);
            }
        }
}

    //
    private void handleServiceArgs(ServiceArgsData data) {
        //获取目标 service
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess();
                }
                int res;
                if (!data.taskRemoved) {
                    //调用onStartCommand
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
                }

                QueuedWork.waitToFinish();

                try {
                    //告诉 AMS 完成
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                } catch (RemoteException e) {
                }
            } catch (Exception e) {
            }
        }
    }
}

至此在一个新进程中的Service启动流程已经结束。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基于 android9.0
  • ​启动流程简述
  • 入口 startService()
  • 【1.1】ContextWrapper.startService()
  • 【1.2】ContextImpl
  • 【2.0】AMS
  • 【2.1】ActiveServices
  • 【2.1】ActivityManagerService.startProcessLocked()
  • 【2.2】 ActivityThread
  • 【2.3】 AMS
  • 【2.4】 ActiveServices
  • 【2.5】ApplicationThread.scheduleCreateService()
  • 【2.6】ApplicationThread.scheduleServiceArgs()
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档