美文网首页进阶
Service工作流程 - bindService

Service工作流程 - bindService

作者: shuixingge | 来源:发表于2016-10-13 22:23 被阅读140次
    一:BindService流程图
    BindService
    补充一:ServiceDispatcher

    bindServiceCommon(): 将客户端的ServiceConnection对象转化为ServiceDispatcher.InnerConnection对象。因为ServiceConnection对象不是一个Binder对象,不能跨进程传输。而其onServiceConnected()方法需要借助AMS回调,所以先要把它转换成对应的Binder对象。

    这个对象就是IServiceConnection(IInterface)接口的实现类ServiceDispatcher.LoadApk

    private boolean  bindServiceCommon(Intent service, ServiceConnection conn, int flags,
               UserHandle user) {
           IServiceConnection sd;
            if (conn == null) {
                throw new IllegalArgumentException("connection is null");
           }
           if (mPackageInfo != null) {
               // LoadApk mPackageInfo
               sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
                        mMainThread.getHandler(), flags);
          } else {
              throw new RuntimeException("Not supported in system context");
            }
           validateServiceIntent(service);
            try {
              IBinder token = getActivityToken();
               if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
                      && mPackageInfo.getApplicationInfo().targetSdkVersion
                        < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                   flags |= BIND_WAIVE_PRIORITY;
              }
              service.prepareToLeaveProcess();
               int res = ActivityManagerNative.getDefault().bindService(
                  mMainThread.getApplicationThread(), getActivityToken(),
                    service, service.resolveTypeIfNeeded(getContentResolver()),
                    sd, flags, user.getIdentifier());
               if (res < 0) {
                   throw new SecurityException(
                          "Not allowed to bind to service " + service);
               }
              return res != 0;
            } catch (RemoteException e) {
                return false;
            }
        }
    

    LoadApk.getServiceDispatcher():首先判段map里面是否存储<ServiceConnection, LoadedApk.ServiceDispatcher>的键值对,如果存储过,就取出当前ServiceConnection对应的LoadedApk.ServiceDispatcher,没有就创建一个ServiceDispatcher对象,并存储。然后根据这个ServiceDispatcher对象取出LoadedApk.ServiceDispatcher.InnerConnection对象。

    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
               Context context, Handler handler, int flags) {
           synchronized (mServices) {
               LoadedApk.ServiceDispatcher sd = null;
                ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
                if (map != null) {
                    sd = map.get(c);
                }
                if (sd == null) {
                   sd = new ServiceDispatcher(c, context, handler, flags);
                    if (map == null) {
                     map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
                        mServices.put(context, map);
                    }
                    map.put(c, sd);
                } else {
                   sd.validate(context, handler);
                }
                return sd.getIServiceConnection();
            }
        }
    

    LoadApk.ServiceDispatcher.InnerConnection:
    这个类是ServiceDispatcher的内部类。而且实现了IServiceConnection.Stub类,所以它是一个Binder对象。可以跨进程传输。在它的内部调用了LoadedApk.ServiceDispatcher的connected()方法。

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

    ServiceDispatcher. connected():
    通过一个 handler传递到主线程;mActivityThread的类型是Handler 。

    public void connected(ComponentName name, IBinder service) {
              if (mActivityThread != null) {
                   mActivityThread.post(new RunConnection(name, service, 0));
              } else {
                   doConnected(name, service);
           }
    
    }
    
    补充二 realStartServiceLocked(): realStartServiceLocked()里面有两个比较重要的方法。分别为

    (1)scheduleCreateService():走创建Service的方法调用链。
    (2)requestServiceBindingsLocked():走Bind Service的方法调用链。

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        
     ...
    
        boolean created = false;
        try {
            synchronized (r.stats.getBatteryStats()) {
                r.stats.startLaunchedLocked();
            }
            mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
            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) {
            mAm.appDiedLocked(app);
            throw e;
        } finally {
          ...
        }
    
        requestServiceBindingsLocked(r, execInFg);
    
        // 不关心,略。。
    }
    

    相关文章

      网友评论

        本文标题:Service工作流程 - bindService

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