美文网首页
Android framework——startService和

Android framework——startService和

作者: Peakmain | 来源:发表于2021-05-10 18:05 被阅读0次

    启动Service

        @Override
        public ComponentName startService(Intent service) {
            return mBase.startService(service);
        }
    

    mBase实际是ContextImpl,所以调用的是ContextImpl的startService

        @Override
        public ComponentName startService(Intent service) {
            warnIfCallingFromSystemProcess();
            return startServiceCommon(service, false, mUser);
        }
        private ComponentName startServiceCommon(Intent service, boolean requireForeground,
                UserHandle user) {
            try {
                validateServiceIntent(service);
                service.prepareToLeaveProcess(this);
                ComponentName cn = ActivityManager.getService().startService(
                    mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                                getContentResolver()), requireForeground,
                                getOpPackageName(), user.getIdentifier());
              .......
                return cn;
            } catch (RemoteException e) {
               .......
            }
        }
    

    ActivityManager.getService返回的是IActivityManager对象,而IActivityManager实际是个AIDL接口,实现类是ActivityManagerService,具体的可以看上篇文章android Framework——Launch Activity的启动过程

        public ComponentName startService(IApplicationThread caller, Intent service,
                String resolvedType, boolean requireForeground, String callingPackage, int userId)
                throws TransactionTooLargeException {
            enforceNotIsolatedCaller("startService");
            synchronized(this) {
               ComponentName res;
                try {
                    res = mServices.startServiceLocked(caller, service,
                            resolvedType, callingPid, callingUid,
                            requireForeground, callingPackage, userId);
                } finally {
                    Binder.restoreCallingIdentity(origId);
                }
                return res;
            }
        }
    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
                int callingPid, int callingUid, String callingPackage, final int userId)
                throws TransactionTooLargeException {
          ...
            return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
        }
        ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
                boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
          String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
          return r.name;
    }
     private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
                boolean whileRestarting, boolean permissionsReviewRequired)
                throws TransactionTooLargeException {
            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);
                if (app != null && app.thread != null) {
                    try {
                        app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
                        realStartServiceLocked(r, app, execInFg);
                        return null;
                    } catch (TransactionTooLargeException e) {
                        throw e;
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception when starting service " + r.shortName, e);
                    }
                }
            } else {
                app = r.isolatedProc;
                if (WebViewZygote.isMultiprocessEnabled()
                        && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
                    hostingType = "webview_service";
                }
            }
    }
    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
       ...
        try {
           ...
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
          ...
        } 
        ...
    }
    

    最终实际调用的是app.thread的scheduleCreateService方法。app.thread是IApplicationThread类型,它的实现类是ActivityThread内部类ApplicationThread

     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;
    
                sendMessage(H.CREATE_SERVICE, s);
            }
    case CREATE_SERVICE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                        handleCreateService((CreateServiceData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
    
        private void handleCreateService(CreateServiceData data) {
            unscheduleGcIdler();
    
            LoadedApk packageInfo = getPackageInfoNoCheck(
                    data.info.applicationInfo, data.compatInfo);
            Service service = null;
            try {
              //获取类加载器
                java.lang.ClassLoader cl = packageInfo.getClassLoader();
                service = packageInfo.getAppFactory()
                        .instantiateService(cl, data.info.name, data.intent);
            } catch (Exception e) {
       
            }
    
            try {
               //service的上下文对象
                ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
                context.setOuterContext(service);
                Application app = packageInfo.makeApplication(false, mInstrumentation);
                   //初始化service
                service.attach(context, this, data.info.name, data.token, app,
                        ActivityManager.getService());
              //service的oncreate方法启动service
                service.onCreate();
                mServices.put(data.token, service);
            
            } catch (Exception e) {
             
            }
        }
    
    service启动.png

    bindService

        @Override
        public boolean bindService(Intent service, ServiceConnection conn,
                int flags) {
            warnIfCallingFromSystemProcess();
            return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser());
        }
        private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
                handler, UserHandle user) {
            IServiceConnection sd;
            if (conn == null) {
                throw new IllegalArgumentException("connection is null");
            }
            if (mPackageInfo != null) {
              //mPackageInfo实际是LoadedApk,将对象封装成IServiceConnection 
                sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
            } else {
                throw new RuntimeException("Not supported in system context");
            }
            validateServiceIntent(service);
            try {
                IBinder token = getActivityToken();
                service.prepareToLeaveProcess(this);
              //最终实际调用的ActivityManagerService
                int res = ActivityManager.getService().bindService(
                    mMainThread.getApplicationThread(), getActivityToken(), service,
                    service.resolveTypeIfNeeded(getContentResolver()),
                    sd, flags, getOpPackageName(), user.getIdentifier());
      
                return res != 0;
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        public int bindService(IApplicationThread caller, IBinder token, Intent service,
                String resolvedType, IServiceConnection connection, int flags, String callingPackage,
                int userId) throws TransactionTooLargeException {
            synchronized(this) {
                return mServices.bindServiceLocked(caller, token, service,
                        resolvedType, connection, flags, callingPackage, userId);
            }
        }
     int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
                String resolvedType, final IServiceConnection connection, int flags,
                String callingPackage, final int userId) throws TransactionTooLargeException {
         if ((flags&Context.BIND_AUTO_CREATE) != 0) {
                    s.lastActivity = SystemClock.uptimeMillis();
            //会调用realStartServiceLocked然后走到ActivityThread来调用Service的onCreate方法
                    if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                            permissionsReviewRequired) != null) {
                        return 0;
                    }
                }
               //s.app!=null表示已经启动
                if (s.app != null && b.intent.received) {
                    try {
                      //c.conn实际是IServiceConn对象
                        c.conn.connected(s.name, b.intent.binder, false);
                    } catch (Exception e) {
                        Slog.w(TAG, "Failure sending service " + s.shortName
                                + " to connection " + c.conn.asBinder()
                                + " (in " + c.binding.client.processName + ")", e);
                    }
                    if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                        requestServiceBindingLocked(s, b.intent, callerFg, true);
                    }
                } else if (!b.intent.requested) {
                       //false表示不重新绑定
                    requestServiceBindingLocked(s, b.intent, callerFg, false);
                }
    
                getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);
    
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
    
            return 1;
    }
        private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
                boolean execInFg, boolean rebind) throws TransactionTooLargeException {
               //rebind为false则表示不重新绑定请求
            if ((!i.requested || rebind) && i.apps.size() > 0) {
                try {
                    bumpServiceExecutingLocked(r, execInFg, "bind");
                    r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                    // r.app.thread实际是IApplicationThread,实现类是ActivityThread的内部类ApplicationThread
                    r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                            r.app.repProcState);
                } 
            }
            return true;
    }
    
    public final void scheduleBindService(IBinder token, Intent intent,
                    boolean rebind, int processState) {
                updateProcessState(processState, false);
                BindServiceData s = new BindServiceData();
                s.token = token;
                s.intent = intent;
                s.rebind = rebind;//rebind这里是false
    
                if (DEBUG_SERVICE)
                    Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
                            + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
                sendMessage(H.BIND_SERVICE, s);
            }
     case BIND_SERVICE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
                        handleBindService((BindServiceData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
    
        private void handleBindService(BindServiceData data) {
           //取出service
            Service s = mServices.get(data.token);
          
            if (s != null) {
                try {
                    data.intent.setExtrasClassLoader(s.getClassLoader());
                    data.intent.prepareToEnterProcess();
                    try {
                        if (!data.rebind) {//rebind是false
                                //调用service的onBind方法
                            IBinder binder = s.onBind(data.intent);
                            ActivityManager.getService().publishService(
                                    data.token, data.intent, binder);
                        } else {
                            s.onRebind(data.intent);
                            ActivityManager.getService().serviceDoneExecuting(
                                    data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                        }
                        ensureJitEnabled();
                    } 
                }
            }
        }
    

    此时最终实际走到的是ActivityManagerService的publishService方法

        public void publishService(IBinder token, Intent intent, IBinder service) {
            synchronized(this) {
                if (!(token instanceof ServiceRecord)) {
                    throw new IllegalArgumentException("Invalid service token");
                }
                mServices.publishServiceLocked((ServiceRecord)token, intent, service);
            }
        }
        void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
            final long origId = Binder.clearCallingIdentity();
            try {
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
                        + " " + intent + ": " + service);
                if (r != null) {
                    if (b != null && !b.received) {
                        for (int conni=r.connections.size()-1; conni>=0; conni--) {
                            ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                            for (int i=0; i<clist.size(); i++) {
                                ConnectionRecord c = clist.get(i);
                           
                                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
                                try {
                                  //c.conn实际是IServiceConnection,它的实现是LoadApk.ServiceDispatcher.InnerConnection
                                    c.conn.connected(r.name, service, false);
                                }
                            }
                        }
                    }
    
                    serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
                }
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
        }
    

    c.conn实际是IServiceConnection,它的实现是LoadApk.ServiceDispatcher.InnerConnection

    static final class ServiceDispatcher {
            private static class InnerConnection extends IServiceConnection.Stub {
                final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
                InnerConnection(LoadedApk.ServiceDispatcher sd) {
                    mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
                }
                public void connected(ComponentName name, IBinder service) throws RemoteException {
                    LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                    if (sd != null) {
                        sd.connected(name, service);//1
                    }
                }
            }
     }
    public void connected(ComponentName name, IBinder service, boolean dead) {
                if (mActivityThread != null) {
                      //mActivityThread实际是Handler
                    mActivityThread.post(new RunConnection(name, service, 0, dead));
                } else {
                    doConnected(name, service, dead);
                }
            }
    
    

    通过Handler将RunConnection对象运行在主线程

            private final class RunConnection implements Runnable {
                RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
                    mName = name;
                    mService = service;
                    mCommand = command;
                    mDead = dead;
                }
    
                public void run() {
                    if (mCommand == 0) {
                        doConnected(mName, mService, mDead);
                    } else if (mCommand == 1) {
                        doDeath(mName, mService);
                    }
                }
    
                final ComponentName mName;
                final IBinder mService;
                final int mCommand;
                final boolean mDead;
            }
    public void doConnected(ComponentName name, IBinder service) {
        if (old != null) {
            mConnection.onServiceDisconnected(name);
        }
        if (service != null) {
                //最终走到的是onServiceConnected[图片上传失败...(image-e87b06-1620636253896)]
    
            mConnection.onServiceConnected(name, service);//1
        }
    }
    
    service的启动.png

    ANR机制

    由上面代码分析我们可以知道startService会走到ActiveServices的realStartServiceLocked方法

        private final void realStartServiceLocked(ServiceRecord r,
                ProcessRecord app, boolean execInFg) throws RemoteException {
        bumpServiceExecutingLocked(r, execInFg, "create");
            try {
                app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                app.thread.scheduleCreateService(r, r.serviceInfo,
                        mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                        app.repProcState);
                r.postNotification();
                created = true;
            } catch (DeadObjectException e) {
                Slog.w(TAG, "Application dead when creating service " + r);
                mAm.appDiedLocked(app);
                throw e;
            }
    }
    private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
        scheduleServiceTimeoutLocked(r.app);
    }
    void scheduleServiceTimeoutLocked(ProcessRecord proc) {
            if (proc.executingServices.size() == 0 || proc.thread == null) {
                return;
            }
               //发送一个超时消息。埋下炸弹
            Message msg = mAm.mHandler.obtainMessage(
                    ActivityManagerService.SERVICE_TIMEOUT_MSG);
            msg.obj = proc;
              //前台20s,后台200s,如果这段时间消息没有被移除则发生爆炸,也就是ANR
            mAm.mHandler.sendMessageDelayed(msg,
                    proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
        }
    

    那service怎么移除消息的呢,我们继续分析handleCreateService

        private void handleCreateService(CreateServiceData data) {
    
            LoadedApk packageInfo = getPackageInfoNoCheck(
                    data.info.applicationInfo, data.compatInfo);
            Service service = null;
            try {
                //通过反射获取service
                java.lang.ClassLoader cl = packageInfo.getClassLoader();
                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());
                 //service的onCreate方法
                service.onCreate();
                mServices.put(data.token, service);
                try {
                   //拆除炸弹
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            } 
        }
        public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
            synchronized(this) {
                mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
            }
        }
        private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying, boolean finishing) {
          ...
          if (r.executeNesting <= 0) {
            if (r.app != null) {
                r.app.execServicesFg = false;
                r.app.executingServices.remove(r);
                if (r.app.executingServices.size() == 0) {
                    //当前没有正在执行的service
                    mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
              ...
            }
          ...
        }
    final class MainHandler extends Handler {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SERVICE_TIMEOUT_MSG: {
                    mServices.serviceTimeout((ProcessRecord)msg.obj);
                } break;
            }
       }
    }
    void serviceTimeout(ProcessRecord proc) {
            String anrMessage = null;
    
            synchronized(mAm) {
                if (proc.executingServices.size() == 0 || proc.thread == null) {
                    return;
                }
                final long now = SystemClock.uptimeMillis();
                final long maxTime =  now -
                        (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
                ServiceRecord timeout = null;
                long nextTime = 0;
                for (int i=proc.executingServices.size()-1; i>=0; i--) {
                    ServiceRecord sr = proc.executingServices.valueAt(i);
                    if (sr.executingStart < maxTime) {
                        timeout = sr;
                        break;
                    }
                    if (sr.executingStart > nextTime) {
                        nextTime = sr.executingStart;
                    }
                }
                if (timeout != null && mAm.mLruProcesses.contains(proc)) {
                    Slog.w(TAG, "Timeout executing service: " + timeout);
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new FastPrintWriter(sw, false, 1024);
                    pw.println(timeout);
                    timeout.dump(pw, "    ");
                    pw.close();
                    mLastAnrDump = sw.toString();
                    mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
                    mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
                    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) {
                 //当存在timeout的service则执行ANR
                mAm.mAppErrors.appNotResponding(proc, null, null, false, anrMessage);
            }
        }
    
    
    image.png
    image.png

    相关文章

      网友评论

          本文标题:Android framework——startService和

          本文链接:https://www.haomeiwen.com/subject/wnmnrltx.html