Service启动源码分析

开启服务

这里只讲解主要流程和方法

    private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess();
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
            ...
            return cn;
        } catch (RemoteException e) {
            return null;
        }
    }
  • getDefault()
static public IActivityManager getDefault() {
    return gDefault.get();
 }
                                
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        IBinder b = ServiceManager.getService("activity");
         ...
        IActivityManager am = asInterface(b);
        ...
        return am;
    }
};
                                                        
static public IActivityManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
     }
    //这里queryLocalInterface执行返回的是null,所以会执行return new ActivityManagerProxy(obj);
    IActivityManager in =
         (IActivityManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
     }
    return new ActivityManagerProxy(obj);
 } 
  • ActivityManagerNative
    开启服务其实是跨进程的,这里用到Binder机制来实现跨进程通信
class ActivityManagerProxy implements IActivityManager {  
    ......            
    public ComponentName startService(IApplicationThread caller, Intent service,  
                String resolvedType) throws RemoteException  {  
        Parcel data = Parcel.obtain();  
        Parcel reply = Parcel.obtain();  
        data.writeInterfaceToken(IActivityManager.descriptor);  
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);  
        service.writeToParcel(data, 0);  
        data.writeString(resolvedType);  
        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);  //mRemote是ServiceManager.getService("activity") -- ActivityManagerService;
         reply.readException();  
         ComponentName res = ComponentName.readFromParcel(reply);  
         data.recycle();  
         reply.recycle();  
         return res;  
    }     
      ......  
}
  • ActivityManagerService
    经过上面的Binder,会执行到ActivityManagerService的startService方法来
public final class ActivityManagerService extends ActivityManagerNative  
                                   implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {        
     ......       
    public ComponentName startService(IApplicationThread caller, Intent service,  
                    String resolvedType) {        
         ...
        ComponentName res = startServiceLocked(caller, service,  
                          resolvedType, callingPid, callingUid);  
        Binder.restoreCallingIdentity(origId);  
                      return res;  
      }  
    }  
 ......    
}

class ActiveServices implements IActivityManager {  
    ......   
    ComponentName startServiceLocked(IApplicationThread caller,Intent service, String resolvedType,int callingPid, int callingUid, int userId) {
        ......
        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    }
}
  • bringUpServiceLocked
private final String bringUpServiceLocked(ServiceRecord r,int intentFlags, boolean execInFg, boolean whileRestarting) {
            
    //如果该Service已经启动。
    if (r.app != null && r.app.thread != null) {
        sendServiceArgsLocked(r, execInFg, false);
        return null;
    }
     //如果正在等待被重新启动,那么什么也不做。
    if (!whileRestarting && r.restartDelay > 0) {
         return null;
    }
                
                
    //清除等待被重新启动的状态。
    if (mRestartingServices.remove(r)) {
        r.resetRestartCounter();
        clearRestartingIfNeededLocked(r);
    }
    //因为我们马上就要启动该Service,因此去掉它的延时属性。
    if (r.delayed) {
        if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r);
             getServiceMap(r.userId).mDelayedStartList.remove(r);
             r.delayed = false;
         } 
        // Make sure that the user who owns this service is started.  If not,
        // we don't want to allow it to run.
        //确保拥有该服务的用户是已经被启动,如果没有,说明我将不想要它运行
           //个人看源码,这里处理通过绑定服务方式启动Service的处理
          if (mAm.mStartedUsers.get(r.userId) == null) {
                    String msg = "Unable to launch app "
                            + r.appInfo.packageName + "/"
                            + r.appInfo.uid + " for service "
                            + r.intent.getIntent() + ": user " + r.userId + " is stopped";
                    Slog.w(TAG, msg);
                    bringDownServiceLocked(r);
                    return msg;
                }               
            
                // Service is now being launched, its package can't be stopped.
                /**
                    (个人理解)
                    设置包的状态,如果是将要被启动,那么包的状态不能是停止,默认包状态是停止,系统有些广播在应用安装后在没有运行过的情况下接收不到广播,原因应该也是因为包的状态是停止,
                    所以,当应用运行时,不管启动四大组件的那个一个,都会设置新的包状态。设置包状态过程会写入文件保存。
                    
                */
                try {
                    AppGlobals.getPackageManager().setPackageStoppedState(
                            r.packageName, false, r.userId);
                } catch (RemoteException e) {
                } catch (IllegalArgumentException e) {
                    Slog.w(TAG, "Failed trying to unstop package "
                            + r.packageName + ": " + e);
                }    
                
                
                final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;//我决定flags就是配置文件里面的android:属性
                final String procName = r.processName;
                ProcessRecord app;
                //如果不是运行在独立的进程。
                if (!isolated) {
                    app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
                    if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                                + " app=" + app);
                                
                    //如果该进程已经启动,那么调用realStartServiceLocked方法            
                    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);
                        }

                        // If a dead object exception was thrown -- fall through to
                        // restart the application.
                    }
                } else {
                    // If this service runs in an isolated process, then each time
                    // we call startProcessLocked() we will get a new isolated
                    // process, starting another process if we are currently waiting
                    // for a previous process to come up.  To deal with this, we store
                    // in the service any current isolated process it is running in or
                    // waiting to have come up.
                    app = r.isolatedProc;
                }        
                
                //如果该Service所对应的进程没有启动,那么首先启动该进程。
                //比如启动的Service在单独的进程,该进程肯定没有被启动,那么系统会给该Service单独fork一个进程处理。
                if (app == null) {
                    if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                            "service", r.name, false, isolated, false)) == null) {
                        String msg = "Unable to launch app "
                                + r.appInfo.packageName + "/"
                                + r.appInfo.uid + " for service "
                                + r.intent.getIntent() + ": process is bad";
                        Slog.w(TAG, msg);
                        bringDownServiceLocked(r);
                        return msg;
                    }
                    if (isolated) {
                        r.isolatedProc = app;
                    }
                }
                //将该ServiceRecord加入到等待的集合当中,等到新的进程启动之后,再去启动它。
                if (!mPendingServices.contains(r)) {
                    mPendingServices.add(r);
                }                                   
            
            ......
          }
  • realStartServiceLocked
private final void realStartServiceLocked(ServiceRecord r,  
                    ProcessRecord app) throws RemoteException {               
    ......  
    r.app = app;  
    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
    app.services.add(r);          
    bumpServiceExecutingLocked(r, execInFg, "create");
    mAm.updateLruProcessLocked(app, false, null);
    mAm.updateOomAdjLocked();                 
    ......  
     try {  
        ......  
         //通知应用端创建Service对象。
        app.thread.scheduleCreateService(r, r.serviceInfo);   
        ......  
    } finally {  
        ......  
    }  
        ......  
 }
  • bumpServiceExecutingLocked
if (r.executeNesting == 0) {
    r.executeFg = fg;
    ProcessStats.ServiceState stracker = r.getTracker();
    if (stracker != null) {
        stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
     }
    if (r.app != null) {
        r.app.executingServices.add(r);
        r.app.execServicesFg |= fg;
        if (r.app.executingServices.size() == 1) {
            scheduleServiceTimeoutLocked(r.app);
        }
    }
} else if (r.app != null && fg && !r.app.execServicesFg) {
    r.app.execServicesFg = true;
    scheduleServiceTimeoutLocked(r.app);
}              
                        
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
     if (proc.executingServices.size() == 0 || proc.thread == null) {
            return;
    }
    long now = SystemClock.uptimeMillis();
    Message msg = mAm.mHandler.obtainMessage(
                                        ActivityManagerService.SERVICE_TIMEOUT_MSG);
    msg.obj = proc;
     mAm.mHandler.sendMessageAtTime(msg,
    proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
}           
                            
mAm.mHandler是MainHandler对象
                            
    case SERVICE_TIMEOUT_MSG: {
        if (mDidDexOpt) {
                 mDidDexOpt = false;
                 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
                  nmsg.obj = msg.obj;
                  mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
                            return;
                        }
                        mServices.serviceTimeout((ProcessRecord)msg.obj);
                    } break;         
                    void serviceTimeout(ProcessRecord proc) {  
                        ......
                        if (timeout != null && mAm.mLruProcesses.contains(proc)) {
                            Slog.w(TAG, "Timeout executing service: " + timeout);
                            anrMessage = "Executing service " + timeout.shortName;
                        } else {
                            Message msg = mAm.mHandler.obtainMessage(
                                    ActivityManagerService.SERVICE_TIMEOUT_MSG);
                            msg.obj = proc;
                            mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
                                    ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
                        }
                            }
                            if (anrMessage != null) {
                                mAm.appNotResponding(proc, null, null, false, anrMessage);
                            }                       
                    }                               
                            
  • scheduleServiceArgs
private class ApplicationThread extends ApplicationThreadNative {

     public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
                        int flags ,Intent args) {
        ServiceArgsData s = new ServiceArgsData();
        s.token = token;
        s.taskRemoved = taskRemoved;
        s.startId = startId;
        s.flags = flags;
        s.args = args;
        sendMessage(H.SERVICE_ARGS, s);
    }
                    
    //ActivityThread
                case SERVICE_ARGS:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
                    handleServiceArgs((ServiceArgsData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;                  
               }            
            */
           sendServiceArgsLocked(r, execInFg, true);
          
            ......  
          
        }
  • ApplicationThreadNative
    public final void scheduleCreateService(IBinder token, ServiceInfo info,
            CompatibilityInfo compatInfo, int processState) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeStrongBinder(token);
        info.writeToParcel(data, 0);
        compatInfo.writeToParcel(data, 0);
        data.writeInt(processState);
        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }
  • ActivityThread
        private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();  //如果后台将要进行gc回收,那么这个函数将从任务队列里面移除gc回收任务。

                //得到APK相关信息
        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();
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
                        
                        /**
                                static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
                                if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
                                return new ContextImpl(null, mainThread,packageInfo, null, null, false, null, null);
                                }
                        */
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            
            /**
                关键函数:Service :attach
                        public final void attach(
                                Context context,
                                ActivityThread thread, String className, IBinder token,
                                Application application, Object activityManager) {
                            attachBaseContext(context);
                            mThread = thread;           // NOTE:  unused - remove?
                            mClassName = className;
                            mToken = token;
                            mApplication = application;
                            mActivityManager = (IActivityManager)activityManager;
                            mStartCompatibility = getApplicationInfo().targetSdkVersion
                                    < Build.VERSION_CODES.ECLAIR;
                        }  
                        
                        protected void attachBaseContext(Context base) {
                            if (mBase != null) {
                                throw new IllegalStateException("Base context already set");
                            }
                            mBase = base;
                        }       
                        mBase:ContextImpl对象,开启一个新的Activity,Service等对话创建一个ContextImpl对象,里面封装了启动Activity,Service的方法。                      
            */
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
                    
            //执行Service的onCreate方法。       
            service.onCreate();
            //使用token存储Service对象
            mServices.put(data.token, service);
            try {
                
                /**
                    //Retrieve the system's default/global activity manager
                    //其实返回的是:ActivityManagerService对象
                            static public IActivityManager getDefault() {
                                return gDefault.get();
                            }     
                            
                                        
                */
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, 0, 0, 0);
            } catch (RemoteException e) {
                // nothing to do.
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }
  • serviceDoneExecutingLocked
        private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
            boolean finishing) {
                
                ......
                
                //如果沒有执行的服务,这移除消息
                if (r.app.executingServices.size() == 0) {
                    if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
                            "No more executingServices of " + r.shortName);
                    mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
                } else if (r.executeFg) {
                    // Need to re-evaluate whether the app still needs to be in the foreground.
                    for (int i=r.app.executingServices.size()-1; i>=0; i--) {
                        if (r.app.executingServices.valueAt(i).executeFg) {
                            r.app.execServicesFg = true;
                            break;
                        }
                    }
                }     
                        
            ......  
        }
  • handleServiceArgs
    private void handleServiceArgs(ServiceArgsData data) {
        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) {
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }

                QueuedWork.waitToFinish();

                try {
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, 1, data.startId, res);
                } catch (RemoteException e) {
                    // nothing to do.
                }
                ensureJitEnabled();
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to start service " + s
                            + " with " + data.args + ": " + e.toString(), e);
                }
            }
        }
        
      }
  • 补充
    ServiceManager
private void startBootstrapServices() {     
     ...... 
     // Set up the Application instance for the system process and get started.
     mActivityManagerService.setSystemProcess();        
 }

ActivityManagerService

 public void setSystemProcess() {       
    ......          
    ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
    ......
 }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355