继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Service启动源码分析

慕的地10843
关注TA
已关注
手记 1081
粉丝 200
获赞 962

开启服务

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

    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);
    ......
 }



作者:奔跑的平头哥
链接:https://www.jianshu.com/p/7abf30178d4e


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP