zoukankan      html  css  js  c++  java
  • 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方式启动

  • 相关阅读:
    多线程编程:阻塞、并发队列的使用总结
    为什么阿里的程序员那么帅?---原来他们都有"编码规约扫描"神器在手
    多线程编程:多线程并发制单的开发记录【一】
    如何使用线程锁来提高多线程并发效率
    如何在分布式环境中同步solr索引库和缓存信息
    前端性能优化指南
    DOM操作方法、属性
    CSS样式手册
    XSS跨站脚本攻击
    数组和对象的使用方法
  • 原文地址:https://www.cnblogs.com/andy-songwei/p/13509957.html
Copyright © 2011-2022 走看看