美文网首页Android进阶之路Android开发
Android源码阅读,绑定Service源码分析

Android源码阅读,绑定Service源码分析

作者: Sky_Blue | 来源:发表于2018-04-03 14:28 被阅读149次
    一、怎么去分析绑定服务的流程
    带着下面这些疑问去看源码
      1.Service是怎么创建的?
      2.Service是怎么绑定的?
      3.Service的回调在哪里调用?
    
    二、一般绑定一个创建好的远程服务(服务的创建我就不多说)
    public void bind(View view) {
          Intent service = new Intent();
          service.setAction("com.wen.user.service");
          service.setPackage("com.wen.routerdemo");
          // 创建并绑定服务
          bindService(service, conn, Context.BIND_AUTO_CREATE);
    }
    // 绑定解绑的回调类
    ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {         
            Toast.makeText(TestActivity.this, "onServiceConnected", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Toast.makeText(TestActivity.this, "onServiceDisconnected", Toast.LENGTH_SHORT).show();
        }
    };
    
    三、bindService源码分析
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,int flags) {
        // mBase其实是ContextImpl
        return mBase.bindService(service, conn, flags);
    }
    
    四、找到ContextImpl类的bindService方法
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,int flags) {
        // mMainThread是ActivityThread
        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),Process.myUserHandle());
    }
    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) {
            // 创建ServiceDispatcher类和IServiceConnection的实现类
            // ServiceDispatcher类是对ServiceConnection回调和IServiceConnection等一些参数的封装
            // 这个类很关键,后面的回调就是在这里
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
        } 
        try {
            IBinder token = getActivityToken();
            // ActivityManager.getService()通过Binder机制获取到ActivityManagerService
            // 最终会调用ActivityManagerService的bindService方法
            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();
        }
    }
    
    五、找到ActivityManagerService的bindService方法
    public int bindService(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
            int userId) throws TransactionTooLargeException {
        synchronized(this) {
            // 这里又去调用ActiveServices类的bindServiceLocked方法
            return mServices.bindServiceLocked(caller, token, service,
                    resolvedType, connection, flags, callingPackage, userId);
        }
    }
    
    五、再去找ActiveServices类的bindServiceLocked方法
     int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String callingPackage, final int userId) throws TransactionTooLargeException {
            
        // 对查找服务信息的封装
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
                    Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
        
        ServiceRecord s = res.record;
        try {
          
            // 传的flags标记
            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
                s.lastActivity = SystemClock.uptimeMillis();
                // 创建Service的重要方法,返回是空,所以继续往下走。
                if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                        permissionsReviewRequired) != null) {
                    return 0;
                }
            }   
            if (s.app != null && b.intent.received) {
                             
                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                    // 绑定Service的关键方法
                    requestServiceBindingLocked(s, b.intent, callerFg, true);
                }
            } else if (!b.intent.requested) {
                // 绑定Service的关键方法
                requestServiceBindingLocked(s, b.intent, callerFg, false);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
        return 1;
    }
    // 创建Service的重要方法
     private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
        final String procName = r.processName;
        String hostingType = "service";
        ProcessRecord app;
        if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
        
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                    // 锁定要开启的Service
                    realStartServiceLocked(r, app, execInFg);
                    // 这里返回null
                    return null;
                } catch (TransactionTooLargeException e) {
                    throw e;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
                }
    
             
            }
        } else {   
            app = r.isolatedProc;
        
        }     
        return null;
    }
     // 锁定要开启的Service
     private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        
        try {
            // 终于看到希望,调用ActivityThread去创建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 {
            if (!created) {
                // Keep the executeNesting count accurate.
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
    
                // Cleanup.
                if (newService) {
                    app.services.remove(r);
                    r.app = null;
                }
    
                // Retry.
                if (!inDestroying) {
                    scheduleServiceRestartLocked(r, false);
                }
            }
        }
    }
    // 绑定服务的关键方法
    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
       
        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind");
                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                // 绑定服务
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
                
            } 
        }
        return true;
    }
    

    在这里终于看到,调用ActivityThread去创建Service的方法:app.thread.scheduleCreateService()和绑定Service的方法:r.app.thread.scheduleBindService()。

    六、Service的创建

    找到ActivityThread里面scheduleCreateService方法,这方法通过Handler发送个消息,然后来到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 = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {  
        }
        try {        
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            // 调用Service的attach方法
            service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService());
            // 调用Service的onCreate()方法
            service.onCreate();
            //  添加到ArrayMap集合
            mServices.put(data.token, service);
        } catch (Exception e) {
        }
    }
    
    七、Service的绑定

    找到ActivityThread里面scheduleBindService方法,这方法通过Handler发送个消息,然后来到handleBindService方法。

    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) {
                        // 调用服务的onBind()方法,得到IBinder
                        IBinder binder = s.onBind(data.intent);
                        // 调用ActivityServiceManager的publishService方法
                        ActivityManager.getService().publishService(data.token, data.intent, binder);
                    } else {
                        s.onRebind(data.intent);
                        ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
                
                } catch (RemoteException ex) {
                }
            } catch (Exception e) {   
            }
        }
    }
    // 这里是ActivityServiceManager类里面的方法
    public void publishService(IBinder token, Intent intent, IBinder service) {
        synchronized(this) {
            // 调用ActiveServices的publishServiceLocked
            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
        }
    }
     // ActiveServices的publishServiceLocked
     void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
        try {      
            if (r != null) {
                Intent.FilterComparison filter
                        = new Intent.FilterComparison(intent);
                IntentBindRecord b = r.bindings.get(filter);
                if (b != null && !b.received) {
                    b.binder = service;
                    b.requested = true;
                    b.received = true;
                    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);
                            try {
                                // 调用IServiceConnection的connected方法
                                // IServiceConnection在ContextImpl类bindServiceCommon方法里面创建
                                // 去ContextImpl类bindServiceCommon方法找到IServiceConnection的实现类ServiceDispatcher里面的mIServiceConnection
                                // 也就是InnerConnection-->>connected(ComponentName name, IBinder service, boolean dead)
                                c.conn.connected(r.name, service, false);
                            } catch (Exception e) {
                                
                            }
                        }
                    }
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }
     //实现类ServiceDispatcher,这个类在LoadedApk类里面
     static final class ServiceDispatcher {
            private final ServiceDispatcher.InnerConnection mIServiceConnection;
            private final ServiceConnection mConnection;
    
            private static class InnerConnection extends IServiceConnection.Stub {
                final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
    
                InnerConnection(LoadedApk.ServiceDispatcher sd) {
                    mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
                }
                // 1.先来到这里
                public void connected(ComponentName name, IBinder service, boolean dead)
                        throws RemoteException {
                    LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                    if (sd != null) {
                        // 2.调用ServiceDispatcher的connected方法
                        sd.connected(name, service, dead);
                    }
                }
            }
    
            ServiceDispatcher(ServiceConnection conn,
                    Context context, Handler activityThread, int flags) {
                mIServiceConnection = new InnerConnection(this);
                mConnection = conn;
                mContext = context;
                mActivityThread = activityThread;
                mLocation = new ServiceConnectionLeaked(null);
                mLocation.fillInStackTrace();
                mFlags = flags;
            }
    
        
            // 2.调用ServiceDispatcher执行connected方法
            public void connected(ComponentName name, IBinder service, boolean dead) {
                if (mActivityThread != null) {
                    mActivityThread.post(new RunConnection(name, service, 0, dead));
                } else {
                    // 3. 调用doConnected方法
                    doConnected(name, service, dead);
                }
            }
    
            public void doConnected(ComponentName name, IBinder service, boolean dead) {
                // 删掉N行代码
                synchronized (this) {
                    // If there is a new service, it is now connected.
                    if (service != null) {
                        // 执行ServiceConnection连接的回调
                        mConnection.onServiceConnected(name, service);
                    }
                }
            }
            
        }
    
    八、总结
    1.Service的创建是在ActivityThread类的handleCreateService方法里通过反射进行创建的,创建后紧接着调用Service的attach()方法,然后调用onCreate()方法。
    2.紧跟着Service的onBind(Intent intent)方法是在ActivityThread类的handleBindService方法里调用
    3.最后绑定服务的客户端ServiceConnection 类的回调是在ServiceDispatcher这个类调用的 doConnected()方法回调。

    相关文章

      网友评论

        本文标题:Android源码阅读,绑定Service源码分析

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